# RSA 加密的 python 实现

# RSA 库安装

在 python 中,有一个库已经了 RSA 加解密的功能,就是 rsa 库库如其名
使用 pip 安装 rsa 库:

pip install rsa

# RSA 库使用

# 生成密钥

import rsa
(pubKey,privKey) = rsa.newkeys(2048)

使用 rsa.newkeys 生成密钥对,括号内的参数为 RSA 位数

不建议使用 RSA1024 及位以下的密钥,因为 RSA1024 及以下已被破解 (或较易被破解)

可以加入参数 poolsize=int 来使用多线程计算, 概率出现程序循环的问题

3072 位以上的 RSA 秘钥生成可能需要 1 分钟或更长,请确保你有足够的耐心

# 保存与加载秘钥

import rsa
(pubKey,privKey) = rsa.newkeys(2048)
with open("pubkey.pem", "wb") as f:
	f.write(pubKey.save_pkcs1())
with open("privkey.pem", "wb") as f:
    f.write(privKey.save_pkcs1())

使用 wbrb 等方法读取出来的都是 bytes 格式,无需二次转换

将 pub/privkey 对象转换为 bytes 的方法为 key.save_pkcs1

import rsa
with open("pubkey.pem", "rb") as f:
    pubKey = rsa.PublicKey.load_pkcs1(f.read())
 
with open("privkey", "rb") as f:
    privKey = rsa.PrivateKey.load_pkcs1(f.read())

使用 rsa.PublicKey(或PrivateKey).load_pkcs1 方法可以加载字节内的秘钥

# 加密和解密

import rsa
(pubKey,privKey) = rsa.newkeys(2048)
text = b"hello world"
print(rsa.encrypt(text, pubKey))

会输出一串 bytes, 这个就是加密后的结果

公钥加密,私钥解密

RSA 库加密必须使用 bytes 格式,str 可以用 str.encode("utf-8") 转换为 bytes

import rsa
(pubKey,privKey) = rsa.newkeys(2048)
text = b"加密后的内容"
print(rsa.decrypt(text, privKey))

python 中 RSA 库的加密是有长度上限的,一般为: RSA 位数 / 8/3 (或者 2) 个中文字符
RSA 4.0 后已经删除了 bigfile 模块,后续可能会出一篇解决方案

# RSA 与其他算法

# RSA 加密流程

首先,加密双方必须生成一对秘钥对 (长度最好一致)
然后互相交换 publickey 文件:
加密的理想状态
但假如现在出现了一个中间人,他会保存所有监听到的东西:
出现中间人
然后双方使用对方的秘钥进行加密,将密文发送给对方,对方使用自己的私钥解密:
发送数据
此时,双方可以顺利的解密对方发来的数据并进行解密,但中间人呢?
中间人手里只有密文和公钥,并无法进行解密,且不可能暴力破解
这样就实现了信息的安全传输,且私钥并没有外泄

# AES 算法

首先,AES 算法是对称加密算法,这意味着它加解密使用同一个秘钥
现在有用户 A、B, 他们会通过网络交换密文:
image.png
然后熟悉的中间人又出现了,他还是会监听并保存所有内容:
image.png
交换秘钥和密文:
image.png
这时中间人已经可以解密双方的密文了,所以 AES 并不适合在不安全网络下传播

算法各有优点,见总结部分

# 总结

AES (对称加密) 算法更适用于在安全环境下加密大量数据
RSA (非对称加密) 算法适用于在不安全环境下加密少量数据

RSA 加密大量数据太慢了,大量数据可以试试 ECC (假如真的不想用 AES)

RSA 加密原理、大文件下一篇再说