def auto_encrypt(plain: str, sm4_key: str, sm2_key: str, random_str: str, salt: str, isPub=True, raw=True): ''' 传入参数:plain:明文, sm4_key:sm4密钥,sm2_key:sm2密钥,random_str:sm2随机字符串 salt:密文组合的时候需要用到的盐,isPub如果为False,则传入的sm2密钥解释为私钥。 raw=True表示传入SM2的字符串为原生字符串 ''' sm4cipher = sm4_encrypt(plain, sm4_key) sm4cipher = binascii.hexlify(base64.b64decode(sm4cipher)).decode( 'utf-8') #hexlize if raw == True: random_str = binascii.hexlify(random_str.encode()) if isPub == False: sm2_key = binascii.hexlify(sm2_key.encode()) sm2_key = sm2.SM2GenKey(sm2_key) if isinstance(random_str, bytes): random_str = random_str.decode() sm2cipher = sm2_encrypt( binascii.hexlify(sm4_key.encode()).decode(), sm2_key, random_str) salted = sm4cipher + salt MD5 = hashlib.md5(salted.encode()).hexdigest() combined = sm4cipher + MD5 + sm2cipher return combined
def sm2_encrypt(plain: str, pubkey: str, str_random: str, raw=False): ''' 输入 明文字符串,私钥,随机字符串 提供raw=True则默认输入为原生字符串,否则必须为十六进制字符串格式。 注意:pubkey为prikey生成,必须为十六进制格式字符串。 返回两个值,第一个为公钥,第二个为十六进制格式的加密字符串。 ''' if raw: str_random = binascii.hexlify(str_random) plain = binascii.hexlify(plain.encode()).decode() try: assert (len(pubkey) == 128 and len(str_random) == 64) except AssertionError: print("Fail to meet the demands") if (isinstance(plain, bytes)): plain = plain.decode() incre = 62 #字符串分组,组长为62hex*4=248bit,不够的加0 block = [plain[i:i + incre] for i in range(0, len(plain), incre)] if len(block[-1]) < incre: block[-1] += '0' * (incre - len(block[-1])) cipher = [] for each in block: cipher.append(sm2.SM2Encrypt(str_random, pubkey, each)) cipher = ''.join(cipher) return cipher
def decrypt(): print("请输入从平台复制得到的字符串: ") str = input() bhindex = str.find("密图哈希:") ehindex = str.find(',', bhindex) bkeyindex = str.find("密钥:") ekeyindex = str.find(",", bkeyindex) ehash = str[bhindex + 5:ehindex] rawkey = str[bkeyindex + 3:ekeyindex] url = "https://ipfs.io/ipfs/" + ehash imgpath = "enc.png" deimgpath = "output.png" # with request.urlopen(url) as web: # # 为保险起见使用二进制写文件模式,防止编码错误 # with open(imgpath, 'wb') as outfile: # outfile.write(web.read()) print("请输入您的私钥文件路径:") keypath = input() if os.path.isfile(keypath): with open(keypath, 'r') as f: prikey = f.read() imgkey = SM2Python.SM2Decrypt(rawkey, prikey) rc = rc4.RC4(imgkey, imgpath, deimgpath) rc.encrypted() # sm4_d = sm4.Sm4() # sm4_d.sm4_set_key(imgkey, 1) # 解密 # sm4_d.sm4_crypt_ecb(imgpath, deimgpath) os.remove(imgpath) print("图片解密完成,您的原图为output.png") else: print("您输入的文件不存在")
def strdecrypt(): print("请输入等待解密的字符") encstr = input() # bhindex = encstr.find("对方公钥:") # ehindex = len(encstr)-1 # enckey = encstr[bhindex+5: ehindex] print("请输入您的私钥文件路径:") keypath = input() if os.path.isfile(keypath): with open(keypath, 'r') as f: prikey = f.read() strdec = SM2Python.SM2Decrypt(encstr, prikey) dec_m = binascii.a2b_hex(strdec) print("解密出来的字符串:", dec_m.decode()) else: print("您输入的文件不存在")
def strencrypt(): s = getkey.varserification() print("生成的验证码为:", s) ss = binascii.b2a_hex(s.encode()).decode() print("请输入待验证方的公钥:") spubkey = input() if spubkey.isalnum(): pubkey = spubkey else: bhindex = spubkey.find("对方公钥:") ehindex = len(spubkey) pubkey = spubkey[bhindex + 5:ehindex] print(pubkey) str_k = getkey.random_str(64) strenc = SM2Python.SM2Encrypt(str_k, pubkey, ss) print("加密后的字符串为:") print(strenc)
def genKey(): prikey = getkey.random_str(64) pubkey = SM2Python.SM2GenKey(prikey) print("请输入保存公私钥的文件夹, 输入的文件夹不存在则保存在此目录下") path = input() if os.path.exists(path): print(path) with open(path + "/pubkey.pem", "w+") as f: # 以二机制方式追加 f.write(pubkey) with open(path + "/prikey.pem", "w+") as f: # 以二机制方式追加 f.write(prikey) else: with open("pubkey.pem", "w+") as f: # 以二机制方式追加 f.write(pubkey) with open("prikey.pem", "w+") as f: # 以二机制方式追加 f.write(prikey) print("公钥保存为pubkey.pem") print("私钥保存为prikey.pem") print("请保存好您的密钥")
def sm2_decrypt(cipher: str, prikey: str, length=None): ''' 返回十六进制明文字符串,length指明文是否有固定的长度 ''' incre = 254 # 密文快为254*4bit block = [cipher[i:i + incre] for i in range(0, len(cipher), incre)] plain = [] for each in block: plain.append(sm2.SM2Decrypt(each, prikey)) plain = ''.join(plain) plain = list(plain) #print(plain) while plain[-1] == '0': if length != None and len(plain) > length: plain.pop() elif length != None and len(plain) <= length: break else: plain.pop() plain = ''.join(plain) return plain
import SM2Python str_k = "F6000277CA814FFF1D7BA2E499297B0E00F8575DCF5F3480C00FCB7DFFBA743E" str_pubkey = "6456CC2649C6216281EE91DCDC5A75C8E92706C3C9B85362796E8E8277BB34A663C11AF6619F6C5A452626EF2703BE187681A816D988467DED48D17E5E54F613" str_prikey = "50E7324D208DC091C089FB98FAEC64468EAE6789B0F707EDFE86EF7CB754DAEA" str_plain = "B0448E89946BB21EC649FDF3BA46296602182849FBE2D329AAF843DE0D7CA7" print("plain :\n" + str_plain) str_cipher = SM2Python.SM2Encrypt(str_k, str_pubkey, str_plain) print("cipher :\n" + str_cipher) plain = SM2Python.SM2Decrypt(str_cipher, str_prikey) print("decrypt cipher and get plain :\n" + plain) input()
''' @author: eccsdk ''' import SM2Python str_prikey = "92E608FA687C466527931C8A70E3BEB700BD0438A31C5470A4D92DEAD3657408" str_cipher = "44DFAA4384DA7A10DEC311C5AE5CAA9448B129DEB4E3A809287138FDAB22B30685404F639925A77D994ABB3B11FBE6C7B58A2921C0C023DB47E97CEEFF14AFB7CAC6B826D47D7CBD12B27C5C933E4F9CDA3C72001263A9D6FC38CC5414A74B5AF726030BC82F78FE90BAA9033F772B69ED3B8B1C6C" plain = SM2Python.SM2Decrypt(str_cipher, str_prikey) print("plain :" + plain) input()
sm4cipher = cipher[0:i] sm2cipher = cipher[i + 32:] break sm4_key = sm2_decrypt(sm2cipher, sm2_prikey) sm4_key = binascii.unhexlify(sm4_key).decode() sm4cipher = base64.b64encode(binascii.unhexlify(sm4cipher)).decode() plain = sm4_decrypt(sm4cipher, sm4_key) return plain if __name__ == '__main__': ''' Test section,输入最好按照我的格式 ''' plain = '\x60\xAE\x23\xEA' sm4_key = 'AVCDFFSkPksdyuss' #the length of sm4_key must be smaller than 128bit or 16Bytes prikey = 'abcd' * 16 #sm2_key must be 256bit string pubkey = sm2.SM2GenKey(prikey) random_str = "00F8575DCF5F3480C00FCB7DFFBA743E" #256bit string salt = 'salt' encoded = auto_encrypt(plain, sm4_key, pubkey, random_str, salt, isPub=True) print(encoded) decoded = auto_decrypt(encoded, prikey, salt) print(plain) print(decoded)