2015-03-13 99 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