前言:前两篇博客写了RSA非对称加密的PKCS1格式秘钥的加密与解密,后面收到很多同学来问自己公司用的是PKCS8格式的秘钥,要如何加密解密。今天咱们就来解决这个问题。
一、前期准备工作
1、安装第三方库
pip install pycryptodome
2、将公钥,私钥分别存入.pem的文件
公钥文件内容如下:
-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAI4/D
ai9lgfbeLswLcRQPubuSeoh9uQf6Ud5GC1Lr5AMwvSLgKtUdVUQG34hvswJmDdsQ
X0LpLtokKsVdD3mFNstLd4euR9FpMausvvObjQETkXC1OpI4b1x/b2qPr0S0xKtY3Ay
97lmB6LTrZ6L8AKFdI13xQjpPhv7dXTO4SbTAgMBAAECgYA/Mgwjd3b8LqlIoHL00K
HhfuQfvM8vMm41brsrBIEPAlxqwL99XpxyGiHcu6lEhM63cMT3hQC+sgnzuChYh6u
jungAAk8cFeBn6zqyTO3VHHxGiN4ElmPUhnAzicrIciVcapsWZmCGLB1Xs9KLOY4ixlI
qOZKTV9wGRpeQepOyIQJBAMkUX2cNo/ESbaSrP76UQFzg4urzcB5Cb+U1Ggz7LW
OfRs5NCPjCge+uAXc12WlG5/x23Mpjm8Dde6x+dlFgwIcCQQC1GQQYf+uwUzPVN
7FNpK/cl3UoGRFSd0EUdkEfKQYOrA3Zmvvpbr/YO0fPGekc83wOfJzYCMpxAiRG9xK
WpXZVAkEArdl1Wo4KjiVWsqZ06HsY4rR0vJpY93CNeehda5fG+Hj/KOKlvR2+ZdFV5x
GhtUnezQKfhkR0p11Wzh5Qga9bBQJAW/nhl6PYi0wmpiLL/RgobUvLJ9tbbdu9hOvud
Sn7tpXxztQlH1CtROAOv4N0XszW8/CcJCiK0Mx6qkQv/6z3pQJAG5RKpafYJRVJCIhNyt
ZFAoayZ07m+TT14I2aWErGSYuEHif1mTC5vH5bDJsYXh30TWZ4ebT78gXJhkVehZ4xLQ==
-----END PRIVATE KEY-----
私钥文件内容如下:
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCOPw2ovZYH23i7M
C3EUD7m7knqIfbkH+lHeRgtS6+QDML0i4CrVHVVEBt+Ib7MCZg3bEF9C6S7aJCrFXQ
95hTbLS3eHrkfRaTGrrL7zm40BE5FwtTqSOG9cf29qj69EtMSrWNwMve5Zgei062ei/ACh
XSNd8UI6T4b+3V0zuEm0wIDAQAB
-----END PUBLIC KEY-----
二、秘钥加载方式
方式一:读取.pem文件
import traceback
import base64
from Crypto.PublicKey import RSA
#Crypto模块中的pkcs1_v1_5就是pkcs8的格式的秘钥
from Crypto.Cipher import PKCS1_v1_5 as PKCS1_v1_5_Cipher
#从文件读取公钥、私钥
private_key = RSA.import_key(open('privkeyzj.pem').read())
public_key = RSA.import_key(open('pubkeyzj.pem').read())
方式二:秘钥作为参数传递
import traceback
import base64
from Crypto.PublicKey import RSA
#Crypto模块中的pkcs1_v1_5就是pkcs8的格式的秘钥
from Crypto.Cipher import PKCS1_v1_5 as PKCS1_v1_5_Cipher
class RSACrypto(object):
#秘钥作为参数传递
def __init__(self, private_key=None, public_key=None):
privateKey = '-----BEGIN RSA PRIVATE KEY-----\r\n{}\r\n-----END RSA PRIVATE KEY-----'.format(private_key).encode()
publicKey = '-----BEGIN RSA PUBLIC KEY-----\r\n{}\r\n-----END RSA PUBLIC KEY-----'.format(public_key).encode()
self.private_key = RSA.importKey(privateKey)
self.public_key = RSA.importKey(publicKey)
三、分对称加密与解密
import traceback
import base64
from Crypto.PublicKey import RSA
#Crypto模块中的pkcs1_v1_5就是pkcs8的格式的秘钥
from Crypto.Cipher import PKCS1_v1_5 as PKCS1_v1_5_Cipher
class RSACrypto(object):
def __init__(self, private_key=None, public_key=None):
# 秘钥从文件读取
self.private_key = RSA.import_key(open('privkeyzj.pem').read())
self.public_key = RSA.import_key(open('pubkeyzj.pem').read())
self.max_encode_len,self.max_decode_len=self.choice_channel()
# 预加密,获取模值
def choice_channel(self):
try:
msg='test'
models_dict={'64': 512, '128': 1024, "512": 2048}
pk = PKCS1_v1_5_Cipher.new(key=self.public_key)
encrypt_text = pk.encrypt(msg.encode()) # 进行加密
result = base64.b64encode(encrypt_text).decode() # 加密通过base64进行编码
decode_str = base64.b64decode(result)
max_decode_len = len(decode_str)
key_size=models_dict['{}'.format(max_decode_len)]
max_encode_len=int(key_size/8-11)
#print('初始化获取的模值:',max_encode_len,max_decode_len)
return max_encode_len,max_decode_len
except Exception as e:
print(traceback.print_exc(),e)
# 公钥加密
# 初始化公钥--初始化加密方法--加密字符串编码encode()--加密方法加密--加密后进行base64编码---完成
# 公钥分段加密(在用)
def to_encrypt_section(self,msg):
try:
# 加密的 plaintext = max_len 最大长度是 证书key位数/8 - 11, 例如1024 bit的证书,被加密的串最长 1024/8 - 11=117,加密得到的密文长度,却恰恰是密钥的长度
pk = PKCS1_v1_5_Cipher.new(key=self.public_key)
if len(msg) <= self.max_encode_len:
encrypt_text = pk.encrypt(msg.encode()) # 进行加密
result = base64.b64encode(encrypt_text).decode() # 加密通过base64进行编码
return result
else:
encrypt_text = []
for i in range(0, len(msg), self.max_encode_len):
cont = msg[i: (i + self.max_encode_len)]
encrypt_text.append(pk.encrypt(message=cont.encode()))
encrypt_data = b''.join(encrypt_text)
# base64 编码
result = base64.b64encode(s=encrypt_data).decode()
return result
except Exception as e:
print(traceback.print_exc(),e)
#分段解密
def to_decrypt_section(self,msg):
try:
decode_str = base64.b64decode(msg)
decode_msg=PKCS1_v1_5_Cipher.new(key=self.private_key)
#max_decode_len = 128
if len(decode_str) <= self.max_decode_len:
text = decode_msg.decrypt(decode_str, 'DecryptError')
return text.decode() # 解密出来的是字节码格式,decodee转换为字符串
else:
text = []
for i in range(0,len(decode_str),self.max_decode_len):
cont=decode_str[i: (i + self.max_decode_len)]
data = decode_msg.decrypt(ciphertext=cont, sentinel='to_decrypt_section_error')
text.append(data)
decrypt_text=b''.join(text)
result=decrypt_text.decode()
return result
except Exception as e:
print(traceback.print_exc(),e)
if __name__ == '__main__':
cl=RSACrypto() #初始化秘钥
str1='123456'
decodestr=cl.to_encrypt_section(msg=str1)
print("加密后:",decodestr)
str2 = cl.to_decrypt_section(msg=decodestr)
print("解密后:",str2)
输出:
加密后: hP7xEyAGRu/MZjKncRLDzkIo39J6fcWmnKtjhrMVZxTlbWmoqZ3GSte0IUoz7/Sba83m7LjX/8cnPVRZi4K6g4uHBnven0O4QpLlQftTRRTJjWpEUjSBNRMf+IqHBCNgjdlB0W6keKla1z7UlB9WNZUC0uIwJgiFUU7ayEyluhs=
解密后: 123456
四、总结
1、企业常用非对称秘钥格式PKCS1和PKCS8
2、PKCS1格式秘钥和PKCS8格式秘钥只是秘钥格式不一样,加密方式是一样的
3、加密细节详解请参考上两篇文章
欢迎来到testingpai.com!
注册 关于