如何用RSA加密和解密AES密钥并存储到文本文件中

3 投票
2 回答
9788 浏览
提问于 2025-04-21 09:54

Python, Pycrypto, RSA, AES

我正在尝试写一个脚本,用来加密一个文件。这个脚本会先生成一个随机的AES密钥,然后用一个RSA公钥来加密这个AES密钥。加密后的AES密钥会分享给那些拥有私钥的授权人员,他们可以用私钥来解密它。代码如下:

from Crypto.PublicKey import RSA
from Crypto.Cipher import AES
from Crypto import Random

RSAkey = '-----BEGIN PUBLIC KEY-----\nSome RSA Key here\n-----END PUBLIC KEY-----'

RSAkey = RSA.importKey(RSAkey)

key = Random.new().read(32)

enc_key = RSAkey.encrypt(key, '')

enc_key = str(enc_key)

custom_writefile_function('enc_key.txt', enc_key)

我把加密后的密钥(enc_key)转换成字符串,这样我才能把它写入一个文本文件。否则,enc_key.txt里会是一些无意义的东西。不过,问题是,在另一个脚本中,我想解密这个enc_key,以获取用来加密文件的原始AES密钥,但尝试解密这个已经转换成字符串的enc_key时出现了错误:

RSAkey.decrypt(str(RSAkey.encrypt(key, ''))) 错误追踪(最近的调用最后): 文件 "", 第 1 行, 在 文件 "/usr/lib/python2.7/dist-packages/Crypto/PublicKey/RSA.py", 第 174 行, 在 decrypt return pubkey.pubkey.decrypt(self, ciphertext) 文件 "/usr/lib/python2.7/dist-packages/Crypto/PublicKey/pubkey.py", 第 93 行, 在 decrypt plaintext=self._decrypt(ciphertext) 文件 "/usr/lib/python2.7/dist-packages/Crypto/PublicKey/RSA.py", 第 237 行, 在 _decrypt cp = self.key._blind(ciphertext, r) ValueError: 消息太大

代码如下:

RSAkey = custom_readfile_function('private_key.txt', 'r')
RSAkey = RSA.importKey(RSAkey)

enc_key = custom_readfile_function('enc_key.txt', 'r')

aes_key = RSAkey.decrypt(enc_key)

custom_writefile_function('key.txt', str(aes_key), 'w')

我认为问题出在数据类型不匹配上。RSAkey.encrypt(key, '') 返回的是一个元组(tuple),所以我猜RSA.decrypt()也期望这个类型,但我不能把这个类型写入文本文件。因此,当我把它转换成字符串以便写入文件时,在解密时又需要把它转换回元组类型。我该怎么做呢?或者也许还有其他更好的方法可以实现我想要的结果,我还没有考虑到?

谢谢

2 个回答

0

虽然你提问已经过去一年多了,但我还是想给你的问题提供一个实际的解决方案,因为我自己也曾为这个小而让人不舒服的错误而苦恼过,希望能帮助到遇到这种情况的人,快速解决问题。

首先,正如其他回答所建议的,为了让人更容易理解,我会使用base64编码:

enc_key = RSAkey.encrypt(key, '')

enc_key = base64.b64encode(enc_key[0]) 

这里的 [0] 代表的是通过 encrypt 方法生成的元组中的第一个值(也就是加密后的内容)。

然后,当你想要解密的时候,可以调用:

aes_key = RSAkey.decrypt(base64.b64decode(enc_key))

这样应该能返回你原来的明文,而不会出现 ValueError: Message too large 的错误。

3

使用 base 64,而不是直接转换成字符串。

要注意你正在使用的 encrypt 方法的文档

返回值: 一个包含两个项目的元组。第一个项目是和明文(原始数据)同类型的密文(字符串或长整型)。第二个项目总是 None。 覆盖:pubkey.pubkey.encrypt

此外,你 应该 注意以下建议:

注意:这个函数执行的是简单的、基础的 RSA 加密(教科书上的内容)。在实际应用中,你总是需要使用合适的加密填充,不能直接用这个方法加密数据。如果不这样做,可能会导致安全漏洞。建议使用模块 Crypto.Cipher.PKCS1_OAEP 或 Crypto.Cipher.PKCS1_v1_5。

撰写回答