在pycrypto中使用RSA解密大文件? [英] Decrypting Large files with RSA in pycrypto?

查看:81
本文介绍了在pycrypto中使用RSA解密大文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

<预><代码>>>>f = open('10kb','rb')>>>p = open('enc','wb')>>>为真:数据 = f.read(32)如果不是数据:休息enc_data = public_key.encrypt(data,32)p.write(enc_data[0])p.close()f.close()

它给出了输出:

128128.......还有它正在写的许多 128 个块

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

<预><代码>>>>f = open('enc','rb')>>>p = open('dec','wb')>>>为真:数据 = f.read(128)如果不是数据:休息dec_data = private_key.decrypt(data)p.write(dec_data)p.close()f.close()

它给出了输出:

3232.....它正在解密这么多 32 字节的块,然后128128128128回溯(最近一次调用最后一次):文件<pyshell#251>",第 5 行,在 <module> 中enc_data = private_key.decrypt(data)文件/usr/lib/python3/dist-packages/Crypto/PublicKey/RSA.py",第174行,解密返回 pubkey.pubkey.decrypt(self, ciphertext)文件/usr/lib/python3/dist-packages/Crypto/PublicKey/pubkey.py",第93行,解密明文=self._decrypt(密文)文件/usr/lib/python3/dist-packages/Crypto/PublicKey/RSA.py",第 237 行,在 _decryptcp = self.key._blind(密文, r)值错误:消息太大

到输出块大小为 32 的地步,它正在解密,但从 128 开始,它搞砸了.为什么说消息大小太大?有没有更好更快的方法来使用 pycrypto 模块解密大文本文件?

解决方案

部分 答案即将到来 ...

<小时>

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

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

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

有两种方法可以解决:

  1. 总是在它之前写密文块的长度.

    加密:

    data = f.read(readsize)如果不是数据:休息我 += 1enc_data = public_key.encrypt(data, 32)[0]p.write(chr(len(enc_data)))p.write(enc_data)

    解密:

    length = f.read(1)如果不是长度:休息数据 = f.read(ord(length))打印(长度,长度(数据))j += 1dec_data = private_key.decrypt(data)p.write(dec_data[:readsize])

    最后,您必须将密文减小到原始明文大小,因为您在工作时没有使用 PKCS#1 v1.5 填充或 OAEP.

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

    加密:

    data = f.read(readsize)如果不是数据:休息我 += 1enc_data = public_key.encrypt(data, 32)[0]而 len(enc_data) <写入大小:enc_data = "\x00" + enc_datap.write(enc_data)

    解密:

    data = f.read(writesize)如果不是数据:休息j += 1dec_data = private_key.decrypt(data)p.write(dec_data[:readsize])

注意 readsize = 127writesize = 128.这里是两种变体的完整源代码.

<小时>

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

I have been using pycrypto module for encryption and decryption with RSA key pair and algorithm. The problem is when I try encrypting large files (10kB of text file) I take the block size of 32 byte when reading the file and encrypting it

>>> 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()

It gives the output:

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

When I try to decrypt the encrypted file, I need to read it with 128 byte block so as to give back 32 byte blocks,

>>> 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()

It is giving the output:

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

To the point where it is outputting the block size of 32, it is decrypting right, but where it starts with 128, its messing up. Why it is saying Message size too large ? Is there any better and fast way to decrypt large text files using pycrypto module ?

解决方案

Partial answer coming along ...


RSA works on numbers. You only get bytes out of it when you serialize those long integers. Since those numbers don't have a fixed size, they are serialized with as much bytes as are necessary, but not more.

An RSA encryption c = me mod n can result in ciphertexts, which are so much smaller than n, that not all the bytes are filled, because leading zeros of the the number don't have to be serialized.

Sometimes (depending on modulus and plaintext) it may happen that you're writing a 127 byte chunk instead of a 128 byte chunk during encryption, but you're always reading a 128 byte chunk during decryption. That means, you're taking away one byte from the next chunk. When the alignment breaks, you can run into various random behaviors such as a chunk being larger than the modulus and therefore not a valid ciphertext.

There are two ways to solve that:

  1. Always write the length of the ciphertext chunk before it.

    Encryption:

    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)
    

    Decryption:

    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])
    

    At the end you have to reduce the ciphertext to the original plaintext size, because you're working without PKCS#1 v1.5 padding or OAEP.

  2. Pad the zero bytes that are missing during encryption.

    Encryption:

    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)
    

    Decryption:

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

Note that readsize = 127 and writesize = 128. Here are the full source codes for both variants.


Now, this is a partial answer, because this still leads to corrupt files, which are also too short, but at least it fixes the OP's error.

这篇关于在pycrypto中使用RSA解密大文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆