python - 在pycrypto中使用RSA解密大文件?

标签 python encryption rsa python-3.4 pycrypto

我一直在使用 pycrypto 模块通过 RSA key 对和算法进行加密和解密。问题是当我尝试加密大文件(10kB 的文本文件)时,我在读取文件并加密时采用 32 字节的 block 大小

>>> f = open('10kb','rb')
>>> p = open('enc','wb')
>>> while True:
       data = f.read(32)
       if not data:
           break
       enc_data = public_key.encrypt(data,32)
       p.write(enc_data[0])
    p.close()
    f.close()

它给出了输出:

128
128
.......and the many 128 blocks it is writing

当我尝试解密加密文件时,我需要用 128 字节 block 读取它以便返回 32 字节 block ,

>>> f = open('enc','rb')
>>> p = open('dec','wb')
>>> while True:
       data = f.read(128)
       if not data:
           break
       dec_data = private_key.decrypt(data)
       p.write(dec_data)
    p.close()
    f.close()

它正在给出输出:

32
32
.....so many 32 byte blocks it is decrypting, then
128
128
128
128
Traceback (most recent call last):
  File "<pyshell#251>", line 5, in <module>
     enc_data = private_key.decrypt(data)
  File "/usr/lib/python3/dist-packages/Crypto/PublicKey/RSA.py", line 174,   in decrypt
     return pubkey.pubkey.decrypt(self, ciphertext)
  File "/usr/lib/python3/dist-packages/Crypto/PublicKey/pubkey.py", line 93, in decrypt
      plaintext=self._decrypt(ciphertext)
  File "/usr/lib/python3/dist-packages/Crypto/PublicKey/RSA.py", line 237, in _decrypt
      cp = self.key._blind(ciphertext, r)
  ValueError: Message too large

到它输出 block 大小为 32 的地步,它是正确解密的,但是它以 128 开头的地方,它搞砸了。为什么它说 Message size too large ?使用 pycrypto 模块解密大型文本文件是否有更好更快的方法?

最佳答案

部分答案出现了......


RSA 处理数字。当您序列化那些长整数时,您只能从中获取字节。由于这些数字没有固定大小,因此会根据需要使用尽可能多的字节对它们进行序列化,但不会更多。

RSA 加密 c = me mod n 可以产生密文,密文要小得多比 n,并不是所有的字节都被填充,因为不必序列化数字的前导零。

有时(取决于模数和明文)您可能会在加密期间写入 127 字节的 block 而不是 128 字节的 block ,但在解密期间您总是读取 128 字节的 block 。这意味着,您要从下一个 block 中拿走一个字节。当对齐中断时,您可能会遇到各种随机行为,例如 block 大于模数,因此不是有效的密文。

有两种解决方法:

  1. 始终在其前写上密文 block 的长度。

    加密:

    data = f.read(readsize)
    if not data:
        break
    i += 1
    enc_data = public_key.encrypt(data, 32)[0]
    
    p.write(chr(len(enc_data)))
    p.write(enc_data)
    

    解密:

    length = f.read(1)
    if not length:
        break
    data = f.read(ord(length))
    print(length, len(data))
    j += 1
    dec_data = private_key.decrypt(data)
    p.write(dec_data[:readsize])
    

    最后,您必须将密文减少到原始明文大小,因为您在没有 PKCS#1 v1.5 填充或 OAEP 的情况下工作。

  2. 填充加密过程中丢失的零字节。

    加密:

    data = f.read(readsize)
    if not data:
        break
    i += 1
    enc_data = public_key.encrypt(data, 32)[0]
    
    while len(enc_data) < writesize:
        enc_data = "\x00" + enc_data
    p.write(enc_data)
    

    解密:

    data = f.read(writesize)
    if not data:
        break
    j += 1
    dec_data = private_key.decrypt(data)
    p.write(dec_data[:readsize])
    

注意 readsize = 127writesize = 128Here是两个变体的完整源代码。


现在,这是一个部分答案,因为这仍然会导致损坏的文件,这些文件也太短了,但至少它修复了 OP 的错误。

关于python - 在pycrypto中使用RSA解密大文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35683598/

相关文章:

java - RSA 2048 加密解密 - 异常

php - 将 JavaScript 私钥转换为可在 PHP 中使用的私钥

java - Java 中的 RSA 和 BigInteger

python - 正则表达式:处理不可预测的输入:不允许使用尾随(但其他方面都可以)字符

python - 时间戳作为sql查询中的变量

encryption - qbasic 中的维吉尼亚加密

java - 部分文件加密

python - 了解 NumPy 中的轴

Python threading.Thread、范围和垃圾收集

encryption - 如何混淆加密功能的 key ?