python有证书的加密解密实现方法
本篇章节讲解python有证书的加密解密实现方法。分享给大家供大家参考。具体实现方法如下: 最近在做python的加解密工作,同时加完密的串能在php上能解出来,网上也找了一些靠谱的资料,刚好也有时间我就总结了一下python在加密与解密这块的代码,今后可能还能用的上。相对于php而言python这块加解密组件较多的,分别是: python-crypto - 这个组件是基本组件,使用的函式相对比较复杂。 我选择使用的是M2Crypto,公钥与私钥证书生成有两个方式,一种采用RSA生成,另一种是X509生成。我就把这两种加解密代码分享出来,供大家参考,但转载或使用时请写明出处。 一、 RSA标准方式生成的证书 1.加密解密、加密签名、验证加密签名 复制代码 代码如下: #encoding: utf8
import os import M2Crypto #随机数生成器(1024位随机) M2Crypto.Rand.rand_seed(os.urandom(1024)) #生成一个1024位公钥与私密钥证书 Geekso = M2Crypto.RSA.gen_key(1024,65537) Geekso.save_key('aspzz.cn-private.pem',None) Geekso.save_pub_key('aspzz.cn-public.pem') #使用公钥证书加密开始 WriteRSA = M2Crypto.RSA.load_pub_key('aspzz.cn-public.pem') CipherText = WriteRSA.public_encrypt("这是一个秘密消息,只能用私钥进行解密",M2Crypto.RSA.pkcs1_oaep_padding) print "加密的串是:" print CipherText.encode('base64') #对加密串进行签名 MsgDigest = M2Crypto.EVP.MessageDigest('sha1') MsgDigest.update(CipherText) #提示,这里也可以使用私钥签名 #WriteRSA = M2Crypto.RSA.load_key ('aspzz.cn-private.pem') #Signature = WriteRSA.sign_rsassa_pss(MsgDigest.digest()) Signature = Geekso.sign_rsassa_pss(MsgDigest.digest()) print "签名的串是:" print Signature.encode('base64') #使用私钥证书解密开始 ReadRSA = M2Crypto.RSA.load_key ('aspzz.cn-private.pem') try: PlainText = ReadRSA.private_decrypt (CipherText,M2Crypto.RSA.pkcs1_oaep_padding) except: print "解密错误" PlainText = "" if PlainText : print "解密出来的串是:" print PlainText # 验证加密串的签名 MsgDigest = M2Crypto.EVP.MessageDigest('sha1') MsgDigest.update(CipherText) #提示,如果是用私钥签名的那就用公钥验证 #VerifyRSA = M2Crypto.RSA.load_pub_key('Alice-public.pem') #VerifyRSA.verify_rsassa_pss(MsgDigest.digest(),Signature) if Geekso.verify_rsassa_pss(MsgDigest.digest(),Signature) == 1: print "签名正确" else: print "签名不正确" 2.字符串生成签名、验证签名 复制代码 代码如下: #用私钥签名
SignEVP = M2Crypto.EVP.load_key('aspzz.cn-private.pem') SignEVP.sign_init() SignEVP.sign_update('来自这一客(http://www.aspzz.cn)的签名串') StringSignature = SignEVP.sign_final() print "签名串是:" print StringSignature.encode('base64') #用公钥验证签名 PubKey = M2Crypto.RSA.load_pub_key('aspzz.cn-public.pem') VerifyEVP = M2Crypto.EVP.PKey() VerifyEVP.assign_rsa(PubKey) VerifyEVP.verify_init() VerifyEVP.verify_update('来自这一客(http://www.aspzz.cn)的签名串') if VerifyEVP.verify_final(StringSignature) == 1: print "字符串被成功验证。" else: print "字符串验证失败!" 3.给证书加上密码 给证书加密码的好处是即使证书被人拿了,没有密码也用不了。 复制代码 代码如下: def passphrase(v): return '4567890' 生成证书时用 复制代码 代码如下: Geekso.save_key('aspzz.cn-private.pem',callback=passphrase) 使用证书时用 复制代码 代码如下: ReadRSA = RSA.load_key ('aspzz.cn-private.pem',passphrase) 二、 X509标准方式生成的证书 1.生成证书、公钥文件、私钥文件 复制代码 代码如下: import time
from M2Crypto import X509,EVP,RSA,ASN1 def issuer_name(): """ 证书发行人名称(专有名称)。 Parameters: none Return: X509标准的发行人obj. """ issuer = X509.X509_Name() issuer.C = "CN" # 国家名称 issuer.CN = "*.aspzz.cn" # 普通名字 issuer.ST = "Hunan Changsha" issuer.L = "Hunan Changsha" issuer.O = "Geekso Company Ltd" issuer.OU = "Geekso Company Ltd" issuer.Email = "123456@qq.com" return issuer def make_request(bits,cn): """ 创建一个X509标准的请求。 Parameters: bits = 证书位数 cn = 证书名称 Return: 返回 X509 request 与 private key (EVP). """ rsa = RSA.gen_key(bits,65537,None) pk = EVP.PKey() pk.assign_rsa(rsa) req = X509.Request() req.set_pubkey(pk) name = req.get_subject() name.C = "US" name.CN = cn req.sign(pk,'sha256') return req,pk def make_certificate_valid_time(cert,days): """ 从当前时间算起证书有效期几天。 Parameters: cert = 证书obj days = 证书过期的天数 Return: none """ t = long(time.time()) # 获取当前时间 time_now = ASN1.ASN1_UTCTIME() time_now.set_time(t) time_exp = ASN1.ASN1_UTCTIME() time_exp.set_time(t + days * 24 * 60 * 60) cert.set_not_before(time_now) cert.set_not_after(time_exp) def make_certificate(bits): """ 创建证书 Parameters: bits = 证快的位数 Return: 证书,私钥 key (EVP) 与 公钥 key (EVP). """ req,pk = make_request(bits,"localhost") puk = req.get_pubkey() cert = X509.X509() cert.set_serial_number(1) # 证书的序例号 cert.set_version(1) # 证书的版本 cert.set_issuer(issuer_name()) # 发行人信息 cert.set_subject(issuer_name()) # 主题信息 cert.set_pubkey(puk) make_certificate_valid_time(cert,365) # 证书的过期时间 cert.sign(pk,'sha256') return cert,pk,puk # 开始创建 cert,puk= make_certificate(1024) cert.save_pem('aspzz.cn-cret.pem') pk.save_key('aspzz.cn-private.pem',cipher = None,callback = lambda: None) puk.get_rsa().save_pub_key('aspzz.cn-public.pem') 2.用证书加密、私钥文件解密 复制代码 代码如下: def geekso_encrypt_with_certificate(message,cert_loc):
""" cert证书加密,可以用私钥文件解密. Parameters: message = 要加密的串 cert_loc = cert证书路径 Return: 加密串 or 异常串 """ cert = X509.load_cert(cert_loc) puk = cert.get_pubkey().get_rsa() # get RSA for encryption message = base64.b64encode(message) try: encrypted = puk.public_encrypt(message,RSA.pkcs1_padding) except RSA.RSAError as e: return "ERROR encrypting " + e.message return encrypted encrypted = geekso_encrypt_with_certificate('www.aspzz.cn','aspzz.cn-cret.pem') print '加密串',encrypted def geekso_decrypt_with_private_key(message,pk_loc): """ 私钥解密证书生成的加密串 Parameters: message = 加密的串 pk_loc = 私钥路径 Return: 解密串 or 异常串 """ pk = RSA.load_key(pk_loc) # load RSA for decryption try: decrypted = pk.private_decrypt(message,RSA.pkcs1_padding) decrypted = base64.b64decode(decrypted) except RSA.RSAError as e: return "ERROR decrypting " + e.message return decrypted print '解密串',geekso_decrypt_with_private_key(encrypted,'aspzz.cn-private.pem') 3.用私钥加密、证书解密 复制代码 代码如下: def geekso_encrypt_with_private_key(message,pk_loc):
""" 私钥加密 Parameters: message = 加密的串 pk_loc = 私钥路径 Return: 加密串 or 异常串 """ ReadRSA = RSA.load_key(pk_loc); message = base64.b64encode(message) try: encrypted = ReadRSA.private_encrypt(message,RSA.pkcs1_padding) except RSA.RSAError as e: return "ERROR encrypting " + e.message return encrypted encrypted = geekso_encrypt_with_private_key('www.aspzz.cn','aspzz.cn-private.pem') print encrypted def geekso_decrypt_with_certificate(message,cert_loc): """ cert证书解密. Parameters: message = 要解密的串 cert_loc = cert证书路径 Return: 解密后的串 or 异常串 """ cert = X509.load_cert(cert_loc) puk = cert.get_pubkey().get_rsa() try: decrypting = puk.public_decrypt(message,RSA.pkcs1_padding) decrypting = base64.b64decode(decrypting) except RSA.RSAError as e: return "ERROR decrypting " + e.message return decrypting decrypting = geekso_decrypt_with_certificate(encrypted,'aspzz.cn-cret.pem') print decrypting 4.用私钥签名、证书验证签名 复制代码 代码如下: def geekso_sign_with_private_key(message,pk_loc,base64 = True):
""" 私钥签名 Parameters: message = 待签名的串 pk_loc = 私钥路径 base64 = True(bease64处理) False(16进制处理) Return: 签名后的串 or 异常串 """ pk = EVP.load_key(pk_loc) pk.sign_init() try: pk.sign_update(message) signature = pk.sign_final() except EVP.EVPError as e: return "ERROR signature " + e.message return signature.encode('base64') if base64 is True else signature.encode('hex') signature = geekso_sign_with_private_key('www.aspzz.cn','aspzz.cn-private.pem') print signature def geekso_verifysign_with_certificate(message,signature,cert_loc,base64 = True): """ 证书验证签名 Parameters: message = 原来签名的串 signature = 签名后的串 cert_loc = 证书路径文件 base64 = True(bease64处理) False(16进制处理) Return: 成功or失败串 or 异常串 """ signature = signature.decode('base64') if base64 is True else signature.decode('hex') cert = X509.load_cert(cert_loc) puk = cert.get_pubkey().get_rsa() try: verifyEVP = EVP.PKey() verifyEVP.assign_rsa(puk) verifyEVP.verify_init() verifyEVP.verify_update(message) verifysign = verifyEVP.verify_final(signature) if verifysign == 1 : return '成功' else : return '失败' except EVP.EVPError as e: return "ERROR Verify Sign " + e.message print geekso_verifysign_with_certificate('www.aspzz.cn','aspzz.cn-cret.pem') 希望本文所述对大家的Python程序设计有所帮助。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |