PyCrypto et le Python Image Class avait des exemples très utiles sur le jeu avec les images et le cryptage AES. Cette implémentation fonctionne uniquement avec les images BMP ayant certaines caractéristiques. La principale caractéristique qu'une image doit avoir pour que cette solution fonctionne est qu'elle doit être d'une taille multiple de 16 octets (pour la partie de chiffrement, AES ECB fonctionne sur des blocs de 16 octets). Vous pouvez travailler sur l'amélioration de cette option pour accepter plus de formats d'image et un pad de 16 octets multiples.
Si vous ne fournissez pas d'image, une image appropriée du Web est téléchargée automatiquement.
im_show
de Image
est connu pour causer des problèmes sur certaines plates-formes. J'ai testé cela sur une distribution Ubuntu 14.10 et je n'ai rencontré aucun problème. Cela a été testé sur Python 2.7, je travaille toujours sur mes compétences portabilité (vous ne spécifiez pas une version Python dans votre question si ...)
#!/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()
Les images initiales et chiffrées ressemblent à ceci:
Je ne pouvais pas trouver la même image que celle de your link, mais le point de faiblesse de la BCE est toujours fait!
Pourriez-vous fournir plus d'informations à ce sujet? Peut-être du code? Votre titre pourrait être un peu plus représentatif aussi – koukouviou
Je modifie ma demande. Merci – davidad
quel format d'image et visionneuse d'image essayez-vous d'utiliser; l'article lié utilisé ppm, qui est un format simple agréable par opposition à par exemple. jpeg ... mais je ne sais pas si Windows est livré avec un lecteur de ppm par défaut. – Foon