2015-03-13 70 views
1

我想加密图像中的数据,但生成的密文仍然是有效的图像。我使用python中的AES加密图像,然后替换文件中的标题,但窗口无法打开加密的图像。在python中生成带有AES的ECB企鹅

代码

def encrypt_file(self, in_filename, out_filename): 
    filesize = os.path.getsize(in_filename) 
    iv = Random.new().read(AES.block_size) 
    cipher = AES.new(self.key, AES.MODE_ECB, iv) 
    chunksize = 64 * 1024 
    with open(in_filename, 'rb') as infile: 
     with open(out_filename, 'wb') as outfile: 
      outfile.write(struct.pack('<Q', filesize)) 
      outfile.write(iv) 

      while True: 
       chunk = infile.read(chunksize) 
       if len(chunk) == 0: 
        break 
       elif len(chunk) % 16 != 0: 
        chunk += ' ' * (16 - len(chunk) % 16) 
       cifrado = base64.b64encode(cipher.encrypt(chunk)) 
       print cifrado 
       outfile.write(cipher.encrypt(chunk)) 

我想要这个效果: The ECB Penguin

+0

你能提供更多的信息吗?也许有些代码?您的标题也可能更具代表性 – koukouviou 2015-03-13 18:48:14

+0

我编辑我的问题。谢谢 – davidad 2015-03-13 18:53:59

+0

你试图使用什么图像格式和图像查看器;链接的文章使用ppm,这是一个很好的简单格式,而不是例如。 jpeg ...虽然我不知道Windows默认是否带有ppm读取器。 – Foon 2015-03-14 02:11:30

回答

5

PyCryptoPython Image Class在玩弄图像和AES加密方面有非常有用的例子。

此实现仅适用于具有某些特征的BMP图像。图像必须具有的这个解决方案的主要特征是它的大小必须是16字节的倍数(对于加密部分,AES ECB在16字节块上操作)。您可以改进此功能以接受更多图像格式并填充至16字节倍数:)

如果您未提供图像,则会自动从网上下载合适的图像。

im_show from Image已知会在某些平台上导致问题。我在Ubuntu 14.10发行版上测试过,并没有遇到任何问题。这是关于Python 2.7测试,我还在我的便携性技能(你没有在你的问题指定一个Python版本所以...)

#!/usr/bin/python 
import binascii, os.path, urllib, random, Image 
from Crypto.Cipher import AES 

class ECBPenguin(object): 
    ''' 
    A penguin class 
    ''' 
    def __init__(self, img_clr=""): 
     if not img_clr: 
      self.__demo_image__() 
      self.img_clr = "tux_clear.bmp" 
     else: 
      self.img_clr = img_clr 
     self.__get_header__() 

    def __demo_image__(self): 
     ''' 
     Downloads a TUX image compatible for this program: square and with size multiple of 16 
     ''' 
     print "Downloading image..." 
     image = urllib.URLopener() 
     image.retrieve("http://fp-games.googlecode.com/svn/trunk/CodeWeek1/graviTux/data/tux.bmp","tux_clear.bmp") 

    def __get_sizes__(self, dibheader): 
     # Get image's dimensions (at offsets 4 and 8 of the DIB header) 
     DIBheader = [] 
     for i in range(0,80,2): 
      DIBheader.append(int(binascii.hexlify(dibheader)[i:i+2],16)) 
     self.width = sum([DIBheader[i+4]*256**i for i in range(0,4)]) 
     self.height = sum([DIBheader[i+8]*256**i for i in range(0,4)]) 

    def __get_header__(self): 
     ''' 
     Read BMP and DIB headers from input image and write them to output image 
     ''' 
     f_in = open(self.img_clr, 'rb') 
     # BMP is 14 bytes 
     bmpheader = f_in.read(14) 
     # DIB is 40 bytes 
     dibheader = f_in.read(40) 
     self.__get_sizes__(dibheader) 
     self._bmpheader = bmpheader 
     self._dibheader = dibheader 
     f_in.close() 

    def encrypt(self, img_enc = "tux_enc.bmp", key = 'abcdef'): 
     ''' 
     Encrypt the my_penguin 
     ''' 
     self.img_enc = img_enc 
     f_in = open(self.img_clr, 'rb') 
     f_out = open(img_enc, 'wb') 
     f_out.write(self._bmpheader) 
     f_out.write(self._dibheader) 
     row_padded = (self.width * self.height * 3) 
     image_data = f_in.read(row_padded) 
     cleartext = binascii.unhexlify(binascii.hexlify(image_data)) 

     # Initialization Vector 
     IV = ''.join(chr(random.randint(0, 0xFF)) for i in range(16)) 
     # AES ECB mode 
     mode = AES.MODE_ECB 
     # Encryptor 
     encryptor = AES.new(key, mode, IV=IV) 
     # Perform the encryption and write output to file 
     f_out.write(encryptor.encrypt(cleartext)) 
     f_in.close() 
     f_out.close() 

    def show_clr(self): 
     ''' 
     Display cleartext penguin 
     ''' 
     im = Image.open(self.img_clr) 
     im.show() 

    def show_enc(self): 
     ''' 
     Display ciphertext penguin 
     ''' 
     im = Image.open(self.img_enc) 
     im.show() 

def main(): 
    my_penguin = ECBPenguin() 
    my_penguin.show_clr() 
    my_penguin.encrypt() 
    my_penguin.show_enc() 

if __name__ == "__main__": 
    main() 

初始和加密图像看起来是这样的:

Plaintext TUX ECB "Encrypted" TUX

我找不到相同的图像作为一个在your link,但欧洲央行的弱点仍然取得了点!

+0

@davidad是否解决您的问题? – koukouviou 2015-03-21 01:30:41

1

简单来说:

  1. 抢.BMP格式的原始图像。

  2. 保持原始BMP头未加密。

  3. 只加密图像,而不是标题。

  4. 将原始未加密标题放回加密图像的前面。

如果加密已将几个填充字节添加到图像大小,则可能需要稍微调整标头。

+0

谢谢,但我知道这些信息。我想要代码或伪代码。 – davidad 2015-03-18 10:01:33

+0

您遇到困难的四个步骤中的哪一步? “伪代码”涵盖了很多可能性。我的答案可以被看作是非常高级别的伪代码。 – rossum 2015-03-18 12:25:41