源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

python有证书的加密解密实现方法

  • 时间:2020-10-06 19:45 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:python有证书的加密解密实现方法
本文实例讲述了python有证书的加密解密实现方法。分享给大家供大家参考。具体实现方法如下: 最近在做python的加解密工作,同时加完密的串能在php上能解出来,网上也找了一些靠谱的资料,刚好也有时间我就总结了一下python在加密与解密这块的代码,今后可能还能用的上。相对于php而言python这块加解密组件较多的,分别是: python-crypto - 这个组件是基本组件,使用的函式相对比较复杂。 ezPyCrypto - 相对简单,但他作出来的公私钥无法与其他程序相兼容     SSLCrypto - 与 ezPyCrypto 是相同一个作者开发,效率上要比ezPyCrypto 好。但一样不能与其它程序相兼容。 pyopenssl - 似乎是用在https 通讯上的,而我找不到加解密的用法。 M2Crypto - 终于让我找到了,但它有一大缺点,它底层是用 SWIG 与 OpenSSL 交接的。 在Windows安装SWIG 程序是非常难的。 我选择使用的是M2Crypto,公钥与私钥证书生成有两个方式,一种采用RSA生成,另一种是X509生成。我就把这两种加解密代码分享出来,供大家参考,但转载或使用时请写明出处。 [b]一、 RSA标准方式生成的证书[/b] 1.加密解密、加密签名、验证加密签名
[u]复制代码[/u] 代码如下:
#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('jb51.net-private.pem', None) Geekso.save_pub_key('jb51.net-public.pem') #使用公钥证书加密开始 WriteRSA = M2Crypto.RSA.load_pub_key('jb51.net-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 ('jb51.net-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 ('jb51.net-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.字符串生成签名、验证签名
[u]复制代码[/u] 代码如下:
#用私钥签名 SignEVP = M2Crypto.EVP.load_key('jb51.net-private.pem') SignEVP.sign_init() SignEVP.sign_update('来自这一客(http://www.1sucai.cn)的签名串') StringSignature = SignEVP.sign_final() print "签名串是:" print StringSignature.encode('base64') #用公钥验证签名 PubKey = M2Crypto.RSA.load_pub_key('jb51.net-public.pem') VerifyEVP = M2Crypto.EVP.PKey() VerifyEVP.assign_rsa(PubKey) VerifyEVP.verify_init() VerifyEVP.verify_update('来自这一客(http://www.1sucai.cn)的签名串') if VerifyEVP.verify_final(StringSignature) == 1:     print "字符串被成功验证。" else:     print "字符串验证失败!"
3.给证书加上密码 给证书加密码的好处是即使证书被人拿了,没有密码也用不了。
[u]复制代码[/u] 代码如下:
def passphrase(v):     return '4567890'
生成证书时用
[u]复制代码[/u] 代码如下:
Geekso.save_key('jb51.net-private.pem',callback=passphrase)
使用证书时用
[u]复制代码[/u] 代码如下:
ReadRSA = RSA.load_key ('jb51.net-private.pem', passphrase)
[b]二、 X509标准方式生成的证书[/b] 1.生成证书、公钥文件、私钥文件
[u]复制代码[/u] 代码如下:
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 = "*.jb51.net"       # 普通名字     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, pk, puk= make_certificate(1024) cert.save_pem('jb51.net-cret.pem') pk.save_key('jb51.net-private.pem',cipher = None, callback = lambda: None) puk.get_rsa().save_pub_key('jb51.net-public.pem')
2.用证书加密、私钥文件解密
[u]复制代码[/u] 代码如下:
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.1sucai.cn','jb51.net-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, 'jb51.net-private.pem')
3.用私钥加密、证书解密
[u]复制代码[/u] 代码如下:
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.1sucai.cn', 'jb51.net-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, 'jb51.net-cret.pem') print decrypting
4.用私钥签名、证书验证签名
[u]复制代码[/u] 代码如下:
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.1sucai.cn','jb51.net-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.1sucai.cn', signature, 'jb51.net-cret.pem')
希望本文所述对大家的Python程序设计有所帮助。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部