Python3.7 基于 pycryptodome 的AES加密解密、RSA加密解密、加签验签
Python3.7基于pycryptodome的AES加密解密、RSA加密解密、加签验签,具体代码如下所示:
#!/usr/bin/envpython #-*-coding:utf8-*- importos importrsa importjson importhashlib importbase64 fromCrypto.CipherimportAES from..settings_managerimportsettings classRSAEncrypter(object): """RSA加密解密 参考https://stuvel.eu/python-rsa-doc/index.html 对应JavaScript版本参考https://github.com/travist/jsencrypt [description] """ @classmethod defencrypt(cls,plaintext,keydata): #明文编码格式 content=plaintext.encode('utf8') ifos.path.isfile(keydata): withopen(keydata)aspublicfile: keydata=publicfile.read() pubkey=rsa.PublicKey.load_pkcs1_openssl_pem(keydata) #公钥加密 crypto=rsa.encrypt(content,pubkey) returnbase64.b64encode(crypto).decode('utf8') @classmethod defdecrypt(cls,ciphertext,keydata): ifos.path.isfile(keydata): withopen(keydata)asprivatefile: keydata=privatefile.read() try: ciphertext=base64.b64decode(ciphertext) privkey=rsa.PrivateKey.load_pkcs1(keydata,format='PEM') con=rsa.decrypt(ciphertext,privkey) returncon.decode('utf8') exceptExceptionase: pass returnFalse @classmethod defsigning(cls,message,privkey): """签名 https://legrandin.github.io/pycryptodome/Doc/3.2/Crypto.Signature.pkcs1_15-module.html """ fromCrypto.Signatureimportpkcs1_15 fromCrypto.HashimportSHA256 fromCrypto.PublicKeyimportRSA ifos.path.isfile(privkey): withopen(privkey)asprivatefile: privkey=privatefile.read() try: key=RSA.import_key(privkey) h=SHA256.new(message.encode('utf8')) sign=pkcs1_15.new(key).sign(h) sign=base64.b64encode(sign).decode('utf8') returnsign exceptExceptionase: raisee @classmethod defverify(cls,message,sign,pubkey): """验证签名 https://legrandin.github.io/pycryptodome/Doc/3.2/Crypto.Signature.pkcs1_15-module.html """ fromCrypto.Signatureimportpkcs1_15 fromCrypto.HashimportSHA256 fromCrypto.PublicKeyimportRSA res=False sign=base64.b64decode(sign) #print('sign',type(sign),sign) try: key=RSA.importKey(pubkey) h=SHA256.new(message.encode('utf8')) pkcs1_15.new(key).verify(h,sign) res=True except(ValueError,TypeError)ase: raisee pass exceptExceptionase: raisee pass returnres classAESEncrypter(object): def__init__(self,key,iv=None): self.key=key.encode('utf8') self.iv=ivifivelsebytes(key[0:16],'utf8') def_pad(self,text): text_length=len(text) padding_len=AES.block_size-int(text_length%AES.block_size) ifpadding_len==0: padding_len=AES.block_size t2=chr(padding_len)*padding_len t2=t2.encode('utf8') #print('text',type(text),text) #print('t2',type(t2),t2) t3=text+t2 returnt3 def_unpad(self,text): pad=ord(text[-1]) returntext[:-pad] defencrypt(self,raw): raw=raw.encode('utf8') raw=self._pad(raw) cipher=AES.new(self.key,AES.MODE_CBC,self.iv) encrypted=cipher.encrypt(raw) returnbase64.b64encode(encrypted).decode('utf8') defdecrypt(self,enc): enc=enc.encode('utf8') enc=base64.b64decode(enc) cipher=AES.new(self.key,AES.MODE_CBC,self.iv) decrypted=cipher.decrypt(enc) returnself._unpad(decrypted.decode('utf8')) classAESSkyPay: """ TestedunderPython3.7andpycryptodome """ BLOCK_SIZE=16 def__init__(self,key): #菲律宾支付通道SkyPayPaymentSpecification.lending.v1.16.pdf #SkyPay对密码做了如下处理 s1=hashlib.sha1(bytes(key,encoding='utf-8')).digest() s2=hashlib.sha1(s1).digest() self.key=s2[0:16] self.mode=AES.MODE_ECB defpkcs5_pad(self,s): """ paddingtoblocksizeaccordingtoPKCS#5 calculatesthenumberofmissingcharstoBLOCK_SIZEandpadswith ord(numberofmissingchars) @see:http://www.di-mgt.com.au/cryptopad.html @params:stringtopad @types:string @rtype:string """ BS=self.BLOCK_SIZE returns+((BS-len(s)%BS)*chr(BS-len(s)%BS)).encode('utf8') defpkcs5_unpad(self,s): """ unpaddingaccordingtoPKCS#5 @params:stringtounpad @types:string @rtype:string """ returns[:-ord(s[len(s)-1:])] #加密函数,如果text不足16位就用空格补足为16位, #如果大于16当时不是16的倍数,那就补足为16的倍数。 #补足方法:PKCS5 defencrypt(self,text): cryptor=AES.new(self.key,self.mode) #这里密钥key长度必须为16(AES-128), #24(AES-192),或者32(AES-256)Bytes长度 #目前AES-128足够目前使用 ciphertext=cryptor.encrypt(self.pkcs5_pad(text.encode('utf8'))) #因为AES加密时候得到的字符串不一定是ascii字符集的,输出到终端或者保存时候可能存在问题 #所以这里将加密的字符串进行base64编码 returnbase64.b64encode(ciphertext).decode() defdecrypt(self,text): cryptor=AES.new(self.key,self.mode) plain_text=cryptor.decrypt(base64.b64decode(text)) returnbytes.decode(self.pkcs5_unpad(plain_text)) defaes_decrypt(ciphertext,secret=None,prefix='aes:::'): secret=secretifsecretelsesettings.default_aes_secret cipher=AESEncrypter(secret) prefix_len=len(prefix) ifciphertext[0:prefix_len]==prefix: returncipher.decrypt(ciphertext[prefix_len:]) else: returnciphertext defaes_encrypt(plaintext,secret=None,prefix='aes:::'): secret=secretifsecretelsesettings.default_aes_secret cipher=AESEncrypter(secret) encrypted=cipher.encrypt(plaintext) return'%s%s'%(prefix,encrypted) if__name__=="__main__": try: #forRSAtest ciphertext='Qa2EU2EF4Eq4w75TnA1IUw+ir9l/nSdW3pMV+a6FkzV9bld259DxM1M4RxYkpPaVXhQFol04yFjuxzkRg12e76i6pkDM1itQSOy5hwmrud5PQvfnBf7OmHpOpS6oh6OQo72CA0LEzas+OANmRXKfn5CMN14GsmfWAn/F6j4Azhs=' public_key='/Users/leeyi/workspace/joywin_staff/joywin_staff_api/datas/public.pem' private_key='/Users/leeyi/workspace/joywin_staff/joywin_staff_api/datas/private.pem' ciphertext=RSAEncrypter.encrypt('admin888中国',public_key) print("ciphertext:",ciphertext) plaintext=RSAEncrypter.decrypt(ciphertext,private_key) print("plaintext:",type(plaintext)) print("plaintext:",plaintext) #forAEStest key='abc20304050607081q2w3e4r*1K|j!ta' cipher=AESEncrypter(key) plaintext='542#1504' encrypted=cipher.encrypt(plaintext) print('Encrypted:%s'%encrypted) ciphertext='EPLtushldq9E1U8vG/sL3g==' assertencrypted==ciphertext plaintext='542#1504你好' encrypted='+YGDvnakKi77SBD6GXmThw==' decrypted=cipher.decrypt(encrypted) print('Decrypted:%s'%decrypted) assertdecrypted==plaintext exceptKeyboardInterrupt: sys.exit(0)
ps:Python3RSA加密解密加签验签示例代码
本代码引入Pycryptodome基于Python3.50版本编译库
#!/usr/bin/envpython3 #coding=utf-8 #Author:Luosu201803 """ create_rsa_key()-创建RSA密钥 my_encrypt_and_decrypt()-测试加密解密功能 rsa_sign()&rsa_signverify()-测试签名与验签功能 """ frombinasciiimportunhexlify fromCrypto.PublicKeyimportRSA fromCrypto.CipherimportPKCS1_OAEP,PKCS1_v1_5 importbase64 fromCrypto.HashimportSHA1 fromCrypto.Signatureimportpkcs1_15 defcreate_rsa_key(password="123456"): """ 创建RSA密钥,步骤说明: 1、从Crypto.PublicKey包中导入RSA,创建一个密码(此密码不是RSA秘钥对) 2、生成1024/2048位的RSA密钥对(存储在私钥文件和公钥文件) 3、调用RSA密钥实例的exportKey方法(传入"密码"、"使用的PKCS标准"、"加密方案"这三个参数)得到私钥。 4、将私钥写入磁盘的文件。 5、使用方法链调用publickey和exportKey方法生成公钥,写入磁盘上的文件。 """ key=RSA.generate(1024) encrypted_key=key.exportKey(passphrase=password,pkcs=8,protection="scryptAndAES128-CBC") #encrypted_key=key.exportKey(pkcs=1) print('encrypted_key:',encrypted_key) withopen("my_private_rsa_key.pem","wb")asf: f.write(encrypted_key) withopen("my_rsa_public.pem","wb")asf: f.write(key.publickey().exportKey()) defencrypt_and_decrypt_test(password="123456"): #加载私钥用于加密 recipient_key=RSA.import_key( open("my_rsa_public.pem").read() ) cipher_rsa=PKCS1_v1_5.new(recipient_key) #使用base64编码保存数据方便查看,同样解密需要base64解码 en_data=base64.b64encode(cipher_rsa.encrypt(b"123456,abcdesd")) print("加密数据信息:",type(en_data),'\n',len(en_data),'\n',en_data) #加载公钥用于解密 encoded_key=open("my_private_rsa_key.pem").read() private_key=RSA.import_key(encoded_key,passphrase=password) cipher_rsa=PKCS1_v1_5.new(private_key) data=cipher_rsa.decrypt(base64.b64decode(en_data),None) print(data) defrsa_sign(message,password="123456"): #读取私钥信息用于加签 private_key=RSA.importKey(open("my_private_rsa_key.pem").read(),passphrase=password) hash_obj=SHA1.new(message) #print(pkcs1_15.new(private_key).can_sign())#checkwheatherobjectofpkcs1_15canbesigned #base64编码打印可视化 signature=base64.b64encode(pkcs1_15.new(private_key).sign(hash_obj)) returnsignature defrsa_signverify(message,signature): #读取公钥信息用于验签 public_key=RSA.importKey(open("my_rsa_public.pem").read()) #message做“哈希”处理,RSA签名这么要求的 hash_obj=SHA1.new(message) try: #因为签名被base64编码,所以这里先解码,再验签 pkcs1_15.new(public_key).verify(hash_obj,base64.b64decode(signature)) print('Thesignatureisvalid.') returnTrue except(ValueError,TypeError): print('Thesignatureisinvalid.') if__name__=='__main__': #create_rsa_key() encrypt_and_decrypt_test() #message=b'LuosuisaMiddle-ageduncle.' #signature=rsa_sign(message) #print('signature:',signature) #print(rsa_signverify(message,signature))
总结
以上所述是小编给大家介绍的Python3.7基于pycryptodome的AES加密解密、RSA加密解密、加签验签,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!