我正在使用pycryptodome
模块及其AES功能来加密某些数据。但是,我需要为AEScipher
生成一个密钥,以便以后检索。该项目以图像的形式存储所有私有数据(包括密钥)。基本上,我们使用像素数组,并使用PIL
创建图像,然后使用getdata()
函数检索pixel_list。
创建图像:-
array = numpy.array(pixels, dtype = numpy.uint8)
new_image = Image.fromarray(array)
new_image.save('user_key.png')
注意,像素是整数元组列表的列表 [[(...), (...)], [(...), (...)], ...]
,这是带有键的对象要从图像获取密钥:-
im = Image.open(image_path)
return list(im.getdata())
现在,我无法直接存储AES key
,假设我使用Crypto模块的Random.get_random_bytes(AES.key_size)
生成了它。
如何生成加密安全密钥,又如何使用pixels
中的密钥之一来检索它,如整数元组?
编辑:-
为了详细说明,像素对象是整数元组列表的列表*,每个元组包含3个整数,每个整数的范围可以从0到255。像素对象的第0个索引可以看起来像这样[(69, 147, 245), (120, 212, 198), ...]
我要指的key_list
对象实际上是list(im.getdata())
。这是一个整数元组列表,每个元组包含3个整数,每个整数的范围可以从0到255。这看起来像这样-[(69, 147, 245), (120, 212, 198)....]
因此,key_list的第0个索引将为(69, 147, 245)
我需要将AES密钥与这些值同等存储。理想情况下,我希望将AES密钥存储为0到255之间的3个整数的元组。所以,是的,我需要将AES密钥转换为元组,然后将其存储在pixels
中。
另外一个关键细节,元组包含3个整数,因为它们分别表示创建图像的RGB值。我相信元组也可以用4个整数表示RGBA值。这样就可以解决3的倍数问题。
但是还有另一个问题。 pixels
中的每个元组实际上都是通过[i for i in itertools.product(range(256), repeat=3)]
生成的。为了生成4个整数而不是3的元组,我必须将repeat=3
更改为repeat=4
,这将引发MemoryError。
这是一个函数,可用于将字节字符串中的值分成指定大小的元组。字节字符串首先打印为整数列表,然后是与之相对应的元组列表。请注意,在示例中,由于字节字符串长度(16)并非3的倍数,因此最后一个元组的后两个值如何用零填充。
from itertools import zip_longest
def grouper(n, iterable, fillvalue=None):
"s -> (s0, s1...sn-1), (sn, sn+1...s2n-1), (s2n, s2n+1...s3n-1), ..."
return zip_longest(*[iter(iterable)]*n, fillvalue=fillvalue)
tuple_size = 3
aes_key = b'\x80in\xbe\x06b\x8f\x8fZ}l-\xb4j\xb5\x1f'
ints = list(aes_key)
tuples = list(grouper(tuple_size, aes_key, fillvalue=0))
print(ints)
print(tuples)
输出:
[128, 105, 110, 190, 6, 98, 143, 143, 90, 125, 108, 45, 180, 106, 181, 31]
[(128, 105, 110), (190, 6, 98), (143, 143, 90), (125, 108, 45), (180, 106, 181), (31, 0, 0)]
由于似乎要用此数据制作图像,所以可能仍然需要根据图像各行中像素的数量进一步格式化该数据。