Python IOError: 不是一个gzip文件 (Gzip和Blowfish加密/压缩)

4

我在使用Python内置库gzip时遇到了一些问题。我已经查看了几乎所有关于它的堆栈问题,但似乎没有一个能解决我的问题。

我的问题在于当我尝试解压缩时,我会得到IOError错误。

我收到的错误信息是:

Traceback (most recent call last):
File "mymodule.py", line 61, in
  return gz.read()
File "/usr/lib/python2.7/gzip.py", line 245,
  readself._read(readsize)
File "/usr/lib/python2.7/gzip.py", line 287, in
  _readself._read_gzip_header()
File "/usr/lib/python2.7/gzip.py", line 181, in
  _read_gzip_header
raise IOError, 'Not a gzipped file'IOError: Not a gzipped file

这是我的代码,用于在网络上传输。可能不太容易理解我为什么这样做,但通常它会在一个while循环中运行且占用内存较少。我只是简化了它。
buffer = cStringIO.StringIO(output) #output is from a subprocess call
small_buffer = cStringIO.StringIO()
small_string = buffer.read() #need a string to write to buffer 
gzip_obj = gzip.GzipFile(fileobj=small_buffer,compresslevel=6, mode='wb')
gzip_obj.write(small_string)
compressed_str = small_buffer.getvalue()

blowfish = Blowfish.new('abcd', Blowfish.MODE_ECB)
remainder = '|'*(8 - (len(compressed_str) % 8))
compressed_str += remainder
encrypted = blowfish.encrypt(compressed_str)
#i send it over smb, then retrieve it later

那么这是检索它的代码:
#buffer is a cStringIO object filled with data from  retrieval
decrypter = Blowfish.new('abcd', Blowfish.MODE_ECB)
value = buffer.getvalue()
decrypted = decrypter.decrypt(value)
buff = cStringIO.StringIO(decrypted)
buff.seek(0)
gz = gzip.GzipFile(fileobj=buff)
return gz.read()

Here's the problem

return gz.read()


2
请注意,您可能永远不应该使用 ECB 模式。 - Dietrich Epp
为什么呢?这是我第一次使用加密和压缩。 - notbad.jpeg
2
ECB不是使用密码的安全方式,从来就不是。看看这只企鹅的图片。http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29 - Dietrich Epp
1
谢谢提醒...现在是另一个问题.. - notbad.jpeg
1个回答

1

编辑:我认为...你忘记在解压之前删除填充了。以下代码适用于我,如果我不删除填充,则会出现相同的错误。

编辑2:填充规范:我认为你正在进行填充的方式需要传递填充大小,因为我假设加密算法也可能使用管道字符。根据RFC 3852,第6.3节,您应该使用所需填充字节数的二进制表示(而不是ASCII数字)进行填充。我更新了下面的代码以执行我的规范解释。

import gzip
import cStringIO
from Crypto.Cipher import Blowfish

#gzip and encrypt
small_buffer = cStringIO.StringIO()
small_string = "test data"
with gzip.GzipFile(fileobj=small_buffer,compresslevel=6, mode='wb') as gzip_obj:
    gzip_obj.write(small_string)
compressed_str = small_buffer.getvalue()
blowfish = Blowfish.new('better than bad')
#remainder = '|'*(8 - (len(compressed_str) % 8))
pad_bytes = 8 - (len(compressed_str) % 8)
padding = chr(pad_bytes)*pad_bytes
compressed_str += padding
encrypted = blowfish.encrypt(compressed_str)
print("encrypted: {}".format(encrypted))



#decrypt and ungzip (pretending to be in a separate space here)
value = encrypted
blowfish = Blowfish.new('better than bad')
decrypted = blowfish.decrypt(value)
buff = cStringIO.StringIO(decrypted)
buff.seek(-1,2) #move to the last byte
pad_bytes = ord(buff.read(1)) #get the size of the padding from the last byte
buff.truncate(len(buff.getvalue()) - pad_bytes) #probably a better way to do this.
buff.seek(0)
with gzip.GzipFile(fileobj=buff) as gz:
    back_home = gz.read()
print("back home: {}".format(back_home))

1
我会测试它,然后给你所有的声望。 - notbad.jpeg
非常感谢@kobejohn!很高兴你为我做了艰苦的研究! - notbad.jpeg
2
@notbad.jpeg 很好,它运行成功了。一切都比预期的要顺利。 - KobeJohn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接