python 3 RSA签名和验签
公司用到微信,支付宝支付,第三方通联支付,采用的都是RSA算法,因此在这记录一下签名和验签的方法。
安装第三方包:pip install pycryptodome
from Crypto.PublicKey import RSA
import Crypto.Signature.PKCS1_v1_5 as sign_PKCS1_v1_5 #用于签名/验签
from Crypto.Cipher import PKCS1_v1_5 #用于加密
from Crypto import Random
from Crypto import Hash
# x = RSA.generate(2048)
# # y = RSA.generate(2048, Random.new().read) #也可以使用伪随机数来辅助生成
# s_key = x.export_key() #私钥
# g_key = x.publickey().export_key() #公钥
# print(s_key,'\n111\n',g_key)
#写入文件--1
# with open("s.pem", "wb") as x:
# x.write(s_key)
# with open("g.pem", "wb") as x:
# x.write(g_key)
#从文件导入密钥 -- 通过私钥生成公钥 (公钥不会变 -- 用于只知道私钥的情况)--2
with open('s.pem','rb')as x:
s_key = RSA.importKey(x.read())
# g_key = s_key.publickey().export_key()
#导入公钥
with open('g.pem','rb')as x:
g_key = RSA.importKey(x.read())
s_key = s_key.export_key()
g_key = g_key.export_key()
# cert = s_key.export_key("DER") #生成证书 -- 它和私钥是唯一对应的
# print(cert)
#实现RSA 非对称加解密
my_private_key = s_key # 私钥
my_public_key = g_key # 公钥
#使用公钥 - 私钥对信息进行加解密
def encrypt_with_rsa(plain_text):
#先公钥加密
cipher_pub_obj = PKCS1_v1_5.new(RSA.importKey(my_public_key))
_secret_byte_obj = cipher_pub_obj.encrypt(plain_text.encode())
return _secret_byte_obj
def decrypt_with_rsa(_secret_byte_obj):
#后私钥解密
cipher_pri_obj = PKCS1_v1_5.new(RSA.importKey(my_private_key))
_byte_obj = cipher_pri_obj.decrypt(_secret_byte_obj, Random.new().read)
plain_text = _byte_obj.decode()
return plain_text
def executer_without_signature():
#加解密验证
text = "info"
assert text == decrypt_with_rsa(encrypt_with_rsa(text))
print("rsa test success!")
# 使用私钥 - 公钥对信息进行签名,验签
def to_sign(plain_text,private_key):
#签名
signer_pri_obj = sign_PKCS1_v1_5.new(RSA.importKey(key))
rand_hash = Hash.SHA256.new()
rand_hash.update(plain_text.encode())
signature = signer_pri_obj.sign(rand_hash)
return signature
def to_verify(signature, plain_text,public_key):
#验签
verifier = sign_PKCS1_v1_5.new(RSA.importKey(key))
_rand_hash = Hash.SHA256.new()
_rand_hash.update(plain_text.encode())
verify = verifier.verify(_rand_hash, signature)
print('verify',verify)
return verify #true / false
def executer_with_signature():
#签名/验签
text = "info"
assert to_verify(to_sign(text,my_private_key), text,my_public_key)
print("rsa Signature verified!")
if __name__ == '__main__' :
executer_without_signature() # 只加密不签名
executer_with_signature() #只签名不加密