在 python 中使用 AES 生成 ECB 企鹅
Produce the ECB penguin with AES in python
我想加密图像中的数据,但生成的密文仍然是有效图像。我在 python 中使用 AES 加密图像,然后,我替换文件中的 header,但是 windows 无法打开加密图像。
代码
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
简单来说:
抓取.BMP格式的原图
保持原始 BMP header 未加密。
只加密图片,不加密 header。
将未加密的原图header放回加密后的图片前面
如果加密为图像大小添加了一些填充字节,您可能需要稍微调整 header。
PyCrypto and the Python Image Class 在处理图像和 AES 加密方面有非常有用的示例。
此实现仅适用于具有特定特征的 BMP 图像。要使此解决方案起作用,图像必须具有的主要特征是它的大小必须是 16 字节的倍数(对于加密部分,AES ECB 在 16 字节块上运行)。您可以改进它以接受更多的图像格式并填充到 16 字节的倍数:)
如果您不提供图片,系统会自动从网络下载合适的图片。
im_show
来自 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 = '0123456789abcdef'):
'''
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()
初始和加密图像如下所示:
没找到和your link一样的图片,但是ECB的弱点还是有的!
我想加密图像中的数据,但生成的密文仍然是有效图像。我在 python 中使用 AES 加密图像,然后,我替换文件中的 header,但是 windows 无法打开加密图像。
代码
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
简单来说:
抓取.BMP格式的原图
保持原始 BMP header 未加密。
只加密图片,不加密 header。
将未加密的原图header放回加密后的图片前面
如果加密为图像大小添加了一些填充字节,您可能需要稍微调整 header。
PyCrypto and the Python Image Class 在处理图像和 AES 加密方面有非常有用的示例。
此实现仅适用于具有特定特征的 BMP 图像。要使此解决方案起作用,图像必须具有的主要特征是它的大小必须是 16 字节的倍数(对于加密部分,AES ECB 在 16 字节块上运行)。您可以改进它以接受更多的图像格式并填充到 16 字节的倍数:)
如果您不提供图片,系统会自动从网络下载合适的图片。
im_show
来自 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 = '0123456789abcdef'):
'''
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()
初始和加密图像如下所示:
没找到和your link一样的图片,但是ECB的弱点还是有的!