Python RSA加解密、为什么RSA公钥每次加密得到的结果都不一样?

文章目录

一、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

上一篇:*crypto*--- 复盘--巅峰极客2020-tryrsa


下一篇:Bugku-CRYPTO-你喜欢下棋吗