文章目录
一、Python Crypto模块RSA加解密
1. RSA加密算法基础
RSA加密算法是一种非对称加密算法。RSA 是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。RSA就是他们三人姓氏开头字母拼在一起组成的 。
RSA加密解密,需要一对秘钥,一个是私钥,一个是公钥。使用公钥加密后,可以用私钥来解密,但使用私钥加密的数据,不能用公钥解密,只能用公钥验证加密后的数据是否被篡改。
2. python 安装Crypto模块
Crypto库的安装比较费心,因为有好几种库可以安装,功能几乎一样,最终都叫Crypto,不同系统下可安装的库的名称还不一致,但总结下来,下面的安装方法在任何平台都可用
pip install pycryptodome
2.1 安装了pycryptodome还是报错ModuleNotFoundError: No module named ‘Crypto’
安装了pycryptodome还是报错
Traceback (most recent call last):
File "F:/code_work/python_test/main.py", line 5, in <module>
from Crypto.PublicKey import RSA
ModuleNotFoundError: No module named 'Crypto'
解决方法:
pip3 unstall crypto
pip3 uninstall pycrypto
pip3 install pycryptodome
亲测可用!
3. 通过RSA生成自己的公钥,私钥
使用Crypto, 可以直接生成私钥和公钥
from Crypto import Random
from Crypto.PublicKey import RSA
def get_rsa_keys():
random_generator = Random.new().read
rsa = RSA.generate(2048, random_generator)
# 生成私钥
private_key = rsa.exportKey()
print(private_key.decode('utf-8'))
# 生成公钥
public_key = rsa.publickey().exportKey()
print(public_key.decode('utf-8'))
with open('rsa_private_key.pem', 'wb')as f:
f.write(private_key)
with open('rsa_public_key.pem', 'wb')as f:
f.write(public_key)
if __name__ == '__main__':
get_rsa_keys()
4. 用公钥加密,私钥解密demo
# coding=utf-8
# This is a sample Python script.
from Crypto import Random
import base64
from Crypto.PublicKey import RSA
from Crypto.Hash import SHA
from Crypto.Signature import PKCS1_v1_5 as PKCS1_signature
from Crypto.Cipher import PKCS1_v1_5 as PKCS1_cipher
def get_rsa_keys():
random_generator = Random.new().read
rsa = RSA.generate(2048, random_generator)
# 生成私钥
private_key = rsa.exportKey()
print(private_key.decode('utf-8'))
# 生成公钥
public_key = rsa.publickey().exportKey()
print(public_key.decode('utf-8'))
with open('rsa_private_key.pem', 'wb')as f:
f.write(private_key)
with open('rsa_public_key.pem', 'wb')as f:
f.write(public_key)
def get_key(key_file):
with open(key_file) as f:
data = f.read()
key = RSA.importKey(data)
return key
def encrypt_data(msg):
public_key = get_key('rsa_public_key.pem')
cipher = PKCS1_cipher.new(public_key)
encrypt_text = base64.b64encode(cipher.encrypt(bytes(msg.encode("utf8"))))
return encrypt_text.decode('utf-8')
def decrypt_data(encrypt_msg):
private_key = get_key('rsa_private_key.pem')
cipher = PKCS1_cipher.new(private_key)
back_text = cipher.decrypt(base64.b64decode(encrypt_msg), 0)
return back_text.decode('utf-8')
def test_encrypt_decrypt():
msg = "hello crypt"
encrypt_text = encrypt_data(msg)
print("encrypt_text:" + encrypt_text)
decrypt_text = decrypt_data(encrypt_text)
print(msg == decrypt_text)
print("decrypt_text:" + decrypt_text)
if __name__ == '__main__':
test_encrypt_decrypt()
5. 为什么RSA公钥每次加密得到的结果都不一样?
为什么RSA公钥每次加密得到的结果都不一样?
参考URL: https://blog.csdn.net/guyongqiangx/article/details/74930951
不管是使用RSA私钥进行签名还是公钥进行加密,操作中都需要对待处理的数据先进行填充,然后再对填充后的数据进行加密处理。针对如何对内容进行填充,"[RFC2313] PKCS #1: RSA Encryption Version 1.5“的”8.1 Encryption-block formatting"
总结: RSA在加密同一个数据过程中,加入了随机数处理(即加盐-salt),这样就导致每次需要加密的明文都是不同的,那么显然密文就每次都不同了。
1)、 密文 =( random+明文) ^e mod n //publicKey 加密
2)、(random+明文) = 密文^d mod n // 服务器端利用privateKey 解密
3)、 明文 = (random+明文) - random //服务器端解码出random
4)、 明文和数据库中数据比较
二、参考
Python crypto模块实现RSA 加密解密
参考URL: https://zhuanlan.zhihu.com/p/181378111
python使用Crypto_PKCS1_v1_5 加密结果不同的解决方法
参考URL: https://blog.csdn.net/weixin_41970395/article/details/108704022