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

2018-09-22 00:48

阅读:597

  本文实例讲述了python有证书的加密解密实现方法。分享给大家供大家参考。具体实现方法如下:

  最近在做python的加解密工作,同时加完密的串能在php上能解出来,网上也找了一些靠谱的资料,刚好也有时间我就总结了一下python在加密与解密这块的代码,今后可能还能用的上。相对于php而言python这块加解密组件较多的,分别是:

  python-crypto - 这个组件是基本组件,使用的函式相对比较复杂。
ezPyCrypto - 相对简单,但他作出来的公私钥无法与其他程序相兼容 SSLCrypto - 与 ezPyCrypto 是相同一个作者开发,效率上要比ezPyCrypto 好。但一样不能与其它程序相兼容。
pyopenssl - 似乎是用在https 通讯上的,而我找不到加解密的用法。
M2Crypto - 终于让我找到了,但它有一大缺点,它底层是用 SWIG 与 OpenSSL 交接的。
在Windows安装SWIG 程序是非常难的。

  我选择使用的是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_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.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.字符串生成签名、验证签名
复制代码 代码如下:#用私钥签名
SignEVP.sign_init()
SignEVP.sign_update(来自这一客(//的签名串)
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(来自这一客(//的签名串)
if VerifyEVP.verify_final(StringSignature) == 1:
print 字符串被成功验证。
else:
print 字符串验证失败!

  3.给证书加上密码

  给证书加密码的好处是即使证书被人拿了,没有密码也用不了。
复制代码 代码如下:def passphrase(v):
return 4567890
生成证书时用
复制代码 代码如下:
使用证书时用
复制代码 代码如下:
二、 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.ST = Hunan Changsha
issuer.L = Hunan Changsha
issuer.O = Geekso Company Ltd
issuer.OU = Geekso Company Ltd
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.用证书加密、私钥文件解密
复制代码 代码如下: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 encrypted
encrypted = geekso_encrypt_with_certificate(
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 解密串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 encrypted
encrypted = geekso_encrypt_with_private_key(
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
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 signature.encode(base64) if base64 is True else signature.encode(hex)
signature = geekso_sign_with_private_key(
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(

  希望本文所述对大家的Python程序设计有所帮助。


评论


亲,登录后才可以留言!