本文为博主原创,未经授权,严禁转载及使用。
本文链接:https://blog.csdn.net/zyooooxie/article/details/120430654
之前写过一篇 https://blog.csdn.net/zyooooxie/article/details/117022776,关于MD5加密、AES加解密ECB、异或加解密的;最近看到项目有些接口参数值要使用rsa加密,简单分享些;
个人博客:https://blog.csdn.net/zyooooxie
RSA非对称加密-公钥加密,私钥解密
非对称加密算法(公开密钥 加密算法),它需要2个密钥,一个public Key,一个private Key。
数据发送方持有公钥,数据接收方持有私钥。
数据发送方通过加密算法和公钥对明文进行加密,得到密文;将密文发送给接收方;数据接收方通过加密算法和私钥对密文进行解密,获得明文。
PEM格式-pkcs#1、pkcs#8
2种格式的 首尾标签
pkcs#8
"""
# 私钥
-----BEGIN PRIVATE KEY-----
-----END PRIVATE KEY-----
# 公钥
-----BEGIN PUBLIC KEY-----
-----END PUBLIC KEY-----
"""
pkcs#1
"""
# 私钥
-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----
# 公钥
-----BEGIN RSA PUBLIC KEY-----
-----END RSA PUBLIC KEY-----
"""
pkcs1格式 与 pkcs8格式公钥转换 可以在网上找到 在线工具;
pkcs8-pycryptodome
生成公钥、私钥
from user_log import Log
from Crypto import Random
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5 as Cipher_PKCS1 # 对应pkcs8
from Crypto.Signature import PKCS1_v1_5 as Signature_PKCS1
import base64
def test_export_rsa(pkcs: int = 8):
random_generator = Random.new().read # 使用 Crypto.Random.new().read 伪随机数生成器
rsa_obj = RSA.generate(2048, random_generator) # 生成RSA密钥对(a new RSA key pair);2048是秘钥的长度
# exportKey() pkcs (*For private keys only*)、format='PEM'、passphrase=None (*For private keys only*)
"""
参数 pkcs=8
# 私钥
-----BEGIN PRIVATE KEY-----
-----END PRIVATE KEY-----
# 公钥
-----BEGIN PUBLIC KEY-----
-----END PUBLIC KEY-----
"""
private_key = rsa_obj.exportKey(pkcs=pkcs) # 生成私钥
with open("private.pem", 'wb') as f:
f.write(private_key)
Log.info('private.pem 已生成')
public_key = rsa_obj.publickey().exportKey(pkcs=pkcs) # 生成公钥
with open("public.pem", 'wb') as f:
f.write(public_key)
Log.info('public.pem 已生成')
手上有公钥、私钥的pem文件,对msg进行加密和解密
def test_rsa_1(msg: str):
"""
使用公钥对内容进行rsa加密
:param msg:
:return:
"""
Log.info('明文msg是:{}'.format(msg))
with open('public.pem') as f:
key = f.read()
# import_key() extern_key (string or byte string)、passphrase=None (For private keys only)
pub_key = RSA.importKey(str(key)) # 对(从文件中读取的)公钥字符串进行处理,处理成可用的加密公钥
# new()key: RSA key object
cipher = Cipher_PKCS1.new(pub_key) # 实例化一个加密对象cipher,传入的参数是公钥
en_str = cipher.encrypt(bytes(msg.encode("utf8")))
rsa_text = base64.b64encode(en_str) # base64 进行编码
Log.info(f"密文是:{
rsa_text.decode('utf-8')}")
# 这里每次使用公钥加密后的结果都不一致,跟 对数据的padding即填充 有关
return rsa_text.decode('utf-8')
def test_rsa_2(encrypted_str: str):
"""
使用私钥对内容进行rsa解密
:param encrypted_str:
:return:
"""
with open('private.pem') as f:
key = f.read()
# 如果私钥有密码 则使用相应密码:import_key() passphrase (string or byte string)
pri_key = RSA.importKey(key) # 对(从文件中读取的)私钥字符串进行处理,处理成可用的解密私钥
cipher = Cipher_PKCS1.new(pri_key) # 实例化一个解密对象 cipher ,传入的参数是私钥
back_text = cipher.decrypt(base64.b64decode(encrypted_str), '解密失败')
# sentinel:The object to return whenever an error is detected.
Log.info('解密后 得到的明文是:{}'.format(back_text.decode('utf-8')))
return back_text.decode('utf-8')
只有公钥、私钥的str,对msg进行加密和解密
def test_encrypt(msg: str, public_key: str):
"""
:param msg:
:param public_key:
:return:
"""
Log.info('明文message是:{}'.format(msg))
pubkey_str = '\n'.join(['-----BEGIN PUBLIC KEY-----', public_key, '-----END PUBLIC KEY-----'])
# Log.info('pubkey_str是:{}'.format(pubkey_str))
cipher = Cipher_PKCS1.new(RSA.importKey(pubkey_str))
crypto = base64.b64encode(cipher.encrypt(msg.encode('utf-8')))
Log.info('密文是:{}'.format(crypto.decode()))
return crypto.decode()
def test_decrypt(encrypted_msg: str, private_key: str):
"""
:param encrypted_msg:
:param private_key:
:return:
"""
private_str = '-----BEGIN PRIVATE KEY-----' + '\n' + private_key + '\n' + '-----END PRIVATE KEY-----'
# Log.info('private_str是:{}'.format(private_str))
cipher = Cipher_PKCS1.new(RSA.importKey(private_str))
decrypt_str = cipher.decrypt(base64.b64decode(encrypted_msg.encode('utf-8')), 'DecryptError')
Log.info('解密后 得到的明文是:{}'.format(decrypt_str.decode()))
return decrypt_str.decode()
pkcs1-rsa
生成公钥、私钥
import rsa
import base64
def test_rsa_export():
# newkeys() nbits: the number of bits required to store
(public_key, private_key) = rsa.newkeys(1024) # Generates public and private keys,and returns them as (pub, priv)
with open('public_1.pem', 'wb') as f:
f.write(public_key.save_pkcs1()) # save_pkcs1() format: str = 'PEM'
Log.info('public_1.pem 已生成')
with open('private_1.pem', 'wb') as f:
f.write(private_key.save_pkcs1())
Log.info('private_1.pem 已生成')
"""
# 私钥
-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----
# 公钥
-----BEGIN RSA PUBLIC KEY-----
-----END RSA PUBLIC KEY-----
"""
只有公钥、私钥的str,对message进行加密和解密
def test_pkcs1_1(message: str, public_key: str, private_key: str):
"""
:param message:
:param public_key:
:param private_key:
:return:
"""
Log.info('明文message是:{}'.format(message))
pubkey_str = '\n'.join(['-----BEGIN RSA PUBLIC KEY-----', public_key, '-----END RSA PUBLIC KEY-----'])
# load_pkcs1() keyfile: bytes, format: str = 'PEM'
pubkey = rsa.PublicKey.load_pkcs1(pubkey_str.encode()) # 返回 the loaded key
# encrypt() message: bytes, pub_key: key.PublicKey
cipher_text = rsa.encrypt(message.encode(), pubkey)
crypto = base64.b64encode(cipher_text) # base64进行二进制编码
Log.info('密文是:{}'.format(crypto.decode()))
private_str = '\n'.join(['-----BEGIN RSA PRIVATE KEY-----', private_key, '-----END RSA PRIVATE KEY-----'])
privkey = rsa.PrivateKey.load_pkcs1(private_str.encode())
# decrypt() crypto: bytes, priv_key: key.PrivateKey
plain_text = rsa.decrypt(cipher_text, privkey)
Log.info('解密后 得到的明文是:{}'.format(plain_text.decode()))
手上有公钥、私钥的pem文件,对message进行加密和解密
def test_pkcs1_2(message: str):
"""
:param message:
:return:
"""
Log.info('明文message是:{}'.format(message))
with open('public_1.pem', 'r') as f:
pubkey = rsa.PublicKey.load_pkcs1(f.read().encode())
crypto_text = rsa.encrypt(message.encode(), pubkey)
crypto = base64.b64encode(crypto_text)
Log.info('密文是:{}'.format(crypto.decode()))
with open('private_1.pem', 'rb') as f:
privkey = rsa.PrivateKey.load_pkcs1(f.read())
plain_text = rsa.decrypt(crypto_text, privkey)
Log.info('解密后 得到的明文是:{}'.format(plain_text.decode()))
实际rsa库是能对pkcs8的公钥 做load的,使用的是 load_pkcs1_openssl_pem()
def test_pkcs8(message: str, public_key: str, private_key: str):
Log.info('明文message是:{}'.format(message))
pubkey_str = """-----BEGIN PUBLIC KEY-----""" + '\n' + public_key + '\n' + """-----END PUBLIC KEY-----"""
pubkey = rsa.PublicKey.load_pkcs1_openssl_pem(pubkey_str.encode())
cipher_text = rsa.encrypt(message.encode(), pubkey)
crypto = base64.b64encode(cipher_text)
Log.info('密文是:{}'.format(crypto.decode()))
这篇内容就这些;本文链接:https://blog.csdn.net/zyooooxie/article/details/120430654
交流技术 欢迎+QQ 153132336 zy
个人博客 https://blog.csdn.net/zyooooxie