现在加密在日常生活中越来越常见,对人来说这是一件好事,但对计算机或者对程序员来说并不一定是件好事。一般来说,加密有对称加密和非对称加密,这里简单介绍下python下rsa非对称密码库的使用
Python Rsa加密与解密使用
网上关于对称加密和非对称加密的解释已经有很多了,这里就不再赘述。简单来说,对称加密只需要一个密钥,而非对称加密需要公钥和私钥两个的密钥。python中已经有帮我们封装好加密算法的库rsa了,简单环境下会使用即可。
以加密PDF文件为例的完整代码:
import rsa
from rsa import common
import time
# 根据传入的安全参数n生成密钥对,返回公钥和私钥
def key_generator(n=256):
pub_key, sec_key = rsa.newkeys(n)
return pub_key, sec_key
# 使用传入的公钥对文件进行加密,返回加密后的密文
def encryption(path, public_keys):
# 获取密文块的明文槽长度
max_message_length = common.byte_size(public_keys.n) - 11
# 以二进制编码读取文件
cipher_text_list = []
with open(path, 'rb') as f:
fs = f.read()
# 设置二进制串的切片轮次
epoch = len(fs) // max_message_length
for i in range(epoch):
# 对原始明文进行切片
fragment = fs[max_message_length * i: max_message_length * (i + 1)]
# 使用公钥对子串进行加密
cipher_text_fragment = rsa.encrypt(fragment, public_key)
# 将密文块填充至列表
cipher_text_list.append(cipher_text_fragment)
# 将最后一部分明文进行加密并填充
cipher_text_list.append(rsa.encrypt(fs[max_message_length * epoch:], public_key))
# 返回密文块列表
return cipher_text_list
# 使用传入的私钥对密文块列表进行解密,返回解密后的明文
def decryption(cipher_text_list, secret_keys):
# 创建明文空间
plain_text = bytes('', 'utf-8')
for fragment in cipher_text_list:
# 使用私钥对密文块进行解密
plain_text_fragment = rsa.decrypt(fragment, secret_keys)
# 将明文串合并至明文空间
plain_text += plain_text_fragment
# 返回明文
return plain_text
if __name__ == "__main__":
start_time = time.time()
path1 = './test1.pdf'
public_key, secret_key = key_generator()
# 以下注释部分为序列化
# import pickle
# pickle.dump(public_key, open('pub_key.bin', 'wb'))
# pickle.dump(secret_key, open('sec_key.bin', 'wb'))
cipher = encryption(path1, public_key)
# pickle.dump(cipher, open('cipher.bin', 'wb'))
# cipher = pickle.load(open('cipher.bin', 'rb'))
# secret_key = pickle.load(open('sec_key.bin', 'rb'))
plain = decryption(cipher, secret_key)
if plain == open(path1, 'rb').read():
print('ok')
else:
print('error')
# with open('test1_0.pdf', 'wb') as f:
# f.write(plain)
end_time = time.time()
print(end_time - start_time, ' seconds.')
pass
一般计算时间和加密内容是正相关的,可以按需要调整参数n,一般为2的次幂。
细心的小伙伴一定也发现了解密过程是最耗时间的。
上述代码中还有签名和验证等方法未涉及,想知道可以自己去尝试。