近来在使用python写项目,特此记录一下项目中遇到的文件加解密问题。
关于python版本的加密算法,随便搜一搜还是可以检索出来很多的,不过大都是同一篇文章在不同的平台来回发布,或者就是转载,而且例举的都是最简单的情况,那么,实际项目中使用的话,肯定会比这个要稍微复杂一些,比如我的需求就是要加密一个使用mysqldump出来的数据库脚本文件,直接拿网上的例子过来调用肯定是不行的,所以不得不自己研究了一番,特此记录。
RSA算法
什么是RSA算法?
项目选型的算法是RSA非对称加密算法,关于这个算法不做过多的解释,咱们划重点:
- 公钥用于加密
- 私钥用于解密
- len_in_byte(raw_data) = len_in_bit(key)/8 -11,如 1024bit 的密钥,一次能加密的内容长度为 1024/8 -11 = 117 byte
为何要减去11个byte?
因为我们使用的是PKCS1Padding占用了11个byte,那么它能加密的明文长度就必须减去这11个byte
可能会遇到什么问题?
基于以上三点,我们大概可以知道要完成文件加解密,我们可能会遇到什么问题?
一次性加密明文的长度是和密钥长度有关系的,那么我们要加密一个文件,不能一次性将文本内容读取出来,然后加密
如果文件很大,我们也不可能将文件内容一次性读取到内存当中,可能会直接导致服务器无法响应其他请求,这肯定是不合理的
文本被加密之后,回头解密,如果读取的长度有差异势必导致解密失败,那么这个数据库备份文件就废了,这个就比较危险了
Do It
安装依赖,python版本3.7.4
pip install pycryptodomex -i https://pypi.tuna.tsinghua.edu.cn/simple/
导入模块:
import base64
from Cryptodome import Random
from Cryptodome.PublicKey import RSA
from Cryptodome.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
from Cryptodome.Signature import PKCS1_v1_5 as Signature_pkcs1_v1_5
生成公钥+私钥,注意这里我们生成的公钥长度是1024bit
# 伪随机数生成器
random_generator = Random.new().read
# rsa算法生成实例
rsa = RSA.generate(1024, random_generator)
private_pem = str(rsa.exportKey(), encoding="utf-8")
with open("client-private.pem", "w") as f:
f.write(private_pem)
public_pem = str(rsa.publickey().exportKey(), encoding="utf-8")
with open("client-public.pem", "w") as f:
f.write(public_pem)'''
加密,这里对传入的明文长度做了切分,因为我们生成的密钥长度为1024bit,所以我们一次加密的明文长度不能超过117个byte
def rsa_encrypt(plaintext, pub_key):
'''
rsa 加密
:param plaintext: 明文
:param pub_key:公钥
'''
message = plaintext.encode("utf-8")
length = len(message)
default_length = 117 # 1024/8 - 11 1024为密钥长度
rsakey = RSA.importKey(pub_key)
cipher = Cipher_pkcs1_v1_5.new(rsakey)
# 不需要切分
if length <= default_length:
return default_rsa_encrypt(cipher, message)