python环境:python3.7_64
python rsa 加密。首先在python里面,有rsa包、pycrypto包、pycryptodome包。(包版本在代码头部注释中)
说一下这个三个包的区别,rsa包是一个pkcs1格式的,后面两个时pkcs8格式。并且pycrypto和pycryptodome是一样的,但是pycrypto安装复杂(需要安装c++等什么组件)所以建议使用pycryptodome包(本文也是使用这个包)。
格式区别如下:
pkcs1格式的pem长这样(头尾有RSA):
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQC5BW6T9GVaaG/epGDjPpY3wN0DrBt+NojvxkEgpUdOAxgAepqe
GbSqtXAd+MOOBbHxIOEwrFC9stkypQgxrB49tXDI+4Jj8MuKI15HEmI8k7+tRDOl
J5TFSL2J9KA3GuQbyVAhlpxl+YnV7yjxP9l1dkbApg1ixSd5KOPbaQ00WQIDAQAB
AoGAYiqzpOTC8dj/og1tKqUGZsZ5fX1PiQO+XBnAbGXFE2sozPhAGSpiZUCnH//h
IfV7mAht8rk6java+bf+RPyhfg0zW7oXy0pm8DwoW7+0fOzQ4sEYeoqza/VrkYwR
5BxBa+KyT1HCi4uXogyDlQT1p0ZT0iaqZBfTApdyVkmcQEECQQDhfPl+ILl0bh0H
8ORoMmmxAZMn293+de441OlAjL3CsF4yhUUdavAYWM0RAV5MJtKUTR4ZpRXkB/pq
kgyTxpr9AkEA0g6pQRpcGxulr2758ZlOLdL8B1n1ubre464IKQ0zNfERKhR/j7U8
LGF+3mhZuoSEdklwLCJ8ZMvIhkV0v8JjjQJBANtqXOyas1vUenNruRabV7ViLuuu
S0p9Px4WMBMb4Ns9+6t1e1ew44kNgB54EmZPsMGWeR/DQJXwHYDuNUbnD5ECQA7S
Gf8N7RG8kaQfIGN7fZieGkoqfrvsA23tCYZb+BEGQT/G0nlBQE2hU2I92pbeYro1
1ERI6p3yAuP2YpZlEMECQGNzhqshYfDiWwU4Q3aZWkRrv74uIXk1HQoFH1BthzQJ
TbzKH/LEqZN8WVau3bf41yAx2YoaOsIJJtOUTYcfh14=
-----END RSA PRIVATE KEY-----
pkcs8格式pem长这样(头尾无RSA):
-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALkFbpP0ZVpob96k
YOM+ljfA3QOsG342iO/GQSClR04DGAB6mp4ZtKq1cB34w44FsfEg4TCsUL2y2TKl
CDGsHj21cMj7gmPwy4ojXkcSYjyTv61EM6UnlMVIvYn0oDca5BvJUCGWnGX5idXv
KPE/2XV2RsCmDWLFJ3ko49tpDTRZAgMBAAECgYBiKrOk5MLx2P+iDW0qpQZmxnl9
fU+JA75cGcBsZcUTayjM+EAZKmJlQKcf/+Eh9XuYCG3yuTqNq9r5t/5E/KF+DTNb
uhfLSmbwPChbv7R87NDiwRh6irNr9WuRjBHkHEFr4rJPUcKLi5eiDIOVBPWnRlPS
JqpkF9MCl3JWSZxAQQJBAOF8+X4guXRuHQfw5GgyabEBkyfb3f517jjU6UCMvcKw
XjKFRR1q8BhYzREBXkwm0pRNHhmlFeQH+mqSDJPGmv0CQQDSDqlBGlwbG6Wvbvnx
mU4t0vwHWfW5ut7jrggpDTM18REqFH+PtTwsYX7eaFm6hIR2SXAsInxky8iGRXS/
wmONAkEA22pc7JqzW9R6c2u5FptXtWIu665LSn0/HhYwExvg2z37q3V7V7DjiQ2A
HngSZk+wwZZ5H8NAlfAdgO41RucPkQJADtIZ/w3tEbyRpB8gY3t9mJ4aSip+u+wD
be0Jhlv4EQZBP8bSeUFATaFTYj3alt5iujXUREjqnfIC4/ZilmUQwQJAY3OGqyFh
8OJbBThDdplaRGu/vi4heTUdCgUfUG2HNAlNvMof8sSpk3xZVq7dt/jXIDHZiho6
wgkm05RNhx+HXg==
-----END PRIVATE KEY-----
好,格式搞清楚后就直接上代码(pkcs1格式的代码):
"""
python3.7_64
rsa==4.7.2
"""
import base64
import json
import re
import rsa
# 生成密钥
def create_pem_key():
"""
生成密钥
:return: 公钥、私钥
"""
(pubkey, privkey) = rsa.newkeys(1024)
return pubkey.save_pkcs1().decode(), privkey.save_pkcs1().decode()
# 公钥加密
def rsadecrypt(pubkey, msg):
"""
公钥加密
:param pubkey: 公钥
:param msg: 需要加密的字符串
:return: 加密后的字符串
"""
msg = json.dumps({"data": msg})
pubkey = rsa.PublicKey.load_pkcs1(pubkey)
data = ''
msglen = len(msg)
# 最大加密长度为:密钥长度/8-11 例如:1024/8-11=117
list = cut_text(msg, 117) # 切片
for item in list:
crypto = rsa.encrypt(item.encode(), pubkey)
crypto = base64.b64encode(crypto).decode()
data = data + crypto + " "
data = data[0:len(data) - 1]
return data
# 私钥解密
def rsacrypto(privkey, data):
"""
私钥解密
:param privkey: 私钥
:param data: 密文
:return: 明文
"""
privkey = rsa.PrivateKey.load_pkcs1(privkey)
list = data.split(' ')
message = ''
for item in list:
if item:
tempmsg = base64.decodebytes(item.encode())
tempmsg = rsa.decrypt(tempmsg, privkey).decode()
message = message + tempmsg
message = json.loads(message)['data']
return message
# 私钥签名
def sign(privkey, data):
"""
私钥签名
:param privkey: 私钥
:param data: 密文
:return: 签名
"""
privkey = rsa.PrivateKey.load_pkcs1(privkey)
signature = rsa.sign(data.encode(), privkey, 'SHA-256')
signature = base64.b64encode(signature).decode()
return signature
# 公钥验证
def checksign(pubkey, sign, data):
"""
公钥验证
:param pubkey: 公钥
:param sign: 签名
:param data: 密文
:return: Ture、False
"""
try:
pubkey = rsa.PublicKey.load_pkcs1(pubkey)
rsa.verify(data.encode(), base64.decodebytes(sign.encode()), pubkey)
return True
except:
return False
# 字符串切割
def cut_text(text, lenth):
textArr = re.findall('.{' + str(lenth) + '}', text)
textArr.append(text[(len(textArr) * lenth):])
return textArr
if __name__ == '__main__':
pubkey, prikey = create_pem_key()
r = rsadecrypt(pubkey, "我的世界12go")
print("加密数据:", r)
msg = rsacrypto(prikey, r)
print('解密数据:', msg)
signstr = sign(prikey, r)
print('签名:', signstr)
result = checksign(pubkey, signstr, r)
print('验证:', result)
pkcs8格式的代码如下:
"""
python3.7_64
pycryptodome==3.10.1
"""
import base64
import json
import re
from Crypto import Random
import Crypto.PublicKey.RSA
from Crypto.Hash import SHA
from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
from Crypto.Signature import PKCS1_v1_5 as Signature_pkcs1_v1_5
from Crypto.PublicKey import RSA
# 生成密钥
def create_pem_key():
"""
生成密钥
:return: 公钥、私钥
"""
# 伪随机数生成器
random_generator = Crypto.Random.new().read
# rsa算法生成实例
rsa = RSA.generate(1024, random_generator)
# master的秘钥对的生成
prikey = rsa.exportKey().decode()
pubkey = rsa.publickey().exportKey().decode()
return (pubkey, prikey)
# 公钥加密
def rsadecrypt(pubkey, msg):
"""
公钥加密
:param pubkey: 公钥
:param msg: 需要加密的字符串
:return: 加密后的字符串
"""
msg = json.dumps({"data": msg})
data = ''
# 最大加密长度为:密钥长度/8-11 例如:1024/8-11=117
list = cut_text(msg, 117) # 切片
for item in list:
rsakey = RSA.importKey(pubkey)
cipher = Cipher_pkcs1_v1_5.new(rsakey)
cipher_text = base64.b64encode(cipher.encrypt(item.encode())).decode()
data = data + cipher_text + " "
data = data[0:len(data) - 1]
return data
# 私钥解密
def rsacrypto(prikey, data):
"""
私钥解密
:param privkey: 私钥
:param data: 密文
:return: 明文
"""
random_generator = Crypto.Random.new().read
list = data.split(' ')
message = ''
for item in list:
if item:
rsakey = RSA.importKey(prikey)
cipher = Cipher_pkcs1_v1_5.new(rsakey)
text = cipher.decrypt(base64.b64decode(item), random_generator).decode()
message = message + text
message = json.loads(message)['data']
return message
# 私钥签名
def sign(prikey, data):
"""
私钥签名
:param privkey: 私钥
:param data: 密文
:return: 签名
"""
rsakey = RSA.importKey(prikey)
signer = Signature_pkcs1_v1_5.new(rsakey)
digest = SHA.new()
digest.update(data.encode())
sign = signer.sign(digest)
signature = base64.b64encode(sign).decode()
return signature
# 公钥验证
def checksign(pubkey, sign, data):
"""
公钥验证
:param pubkey: 公钥
:param sign: 签名
:param data: 密文
:return: Ture、False
"""
try:
rsakey = RSA.importKey(pubkey)
verifier = Signature_pkcs1_v1_5.new(rsakey)
digest = SHA.new()
# Assumes the data is base64 encoded to begin with
digest.update(data.encode())
is_verify = verifier.verify(digest, base64.b64decode(sign))
return is_verify
except:
return False
# 字符串切割
def cut_text(text, lenth):
textArr = re.findall('.{' + str(lenth) + '}', text)
textArr.append(text[(len(textArr) * lenth):])
return textArr
if __name__ == '__main__':
pubkey, prikey = create_pem_key()
r = rsadecrypt(pubkey, "我的世界12go")
print("加密数据:", r)
msg = rsacrypto(prikey, r)
print('解密数据:', msg)
signstr = sign(prikey, r)
print('签名:', signstr)
result = checksign(pubkey, signstr, r)
print('验证:', result)
python后端rsa加密完成后,js前端rsa加密下期更新!