如何从二进制字符串创建图像

时间:2017-06-01 17:46:40

标签: python image rsa

我从文件映像中读取二进制文件,每个128字节并使用rsa进行加密。但加密后我无法从二进制文件创建图像。我创建了funtion genarate key rsa。我将二进制转换为int加密

from PIL import Image
import KeyRSA
import RsaMath

pub, piv = KeyRSA.GenerateRsaKey(size=1024)
n, e = pub

with open("hinh.png", "rb") as infile:
    data = infile.read()
step = 128
cipher_data = []
for i in range(0, len(data), step):
    value = data[i:i+step]
    m = RsaMath.OS2IP(value)
    c = pow(m, e, n)
    cipher_data.append(RsaMath.I2OSP(c, 128))

cipher_data = "".join(cipher_data)

im = Image.open("hinh.png")
W, H = im.size
img = Image.frombytes("RGB", (W,H), cipher_data)
img.show()e here

1 个答案:

答案 0 :(得分:0)

由于我无法访问KeyRSA和RsaMath,因此我决定使用pycrypto包。原始RSA加密安全,而且速度慢,因此该代码使用AES,这种方法很快,在块模式下使用128字节块非常安全。

下面的代码不是从文件中读取图像,而是生成一个简单的双色图像。然后它对其进行加密,将加密数据转换为图像,然后显示并保存为PNG。然后它解密加密数据以恢复原始图像。

加密过程使用128字节块执行,因此如果确实想要这样做,您可以轻松地使其适应您的RSA加密算法。但是,一步执行加密效率更高;我已经添加了一条注释掉的行,说明了如何做到这一点。

#!/usr/bin/env python3

''' Create a simple image and encrypt it with AES

    See https://stackoverflow.com/q/44314026/4014959

    Written by PM 2Ring 2017.06.02
'''

from PIL import Image
from Crypto.Cipher import AES

def color_square(size, colors):
    ''' Make a square that fades diagonally
        from the 1st color to the 2nd color
    '''
    m = 255.0 / (2 * size - 2)
    r = range(size)
    mask = bytes(int(m * (x + y)) for y in r for x in r)
    mask = Image.frombytes('L', (size, size), mask)
    imgs = [Image.new('RGB', (size, size), color=c) for c in colors]
    return Image.composite(imgs[0], imgs[1], mask)

# Create a simple image
size = 128
img = color_square(size, ('red', 'blue'))
img.show()

# Extract the raw pixel data from the image
src_data = img.tobytes()
print('Original length:', len(src_data), size*size*3)

# Create an AES cipher object
key = b'This is a key123'
iv = b'This is an IV456'
crypto = AES.new(key, AES.MODE_CBC, iv)

# Encrypt the data in 128 byte chunks
blocks = []
for i in range(0, len(src_data), 128):
    blocks.append(crypto.encrypt(src_data[i:i+128]))
cipher_data = b''.join(blocks)

# We could actually encrypt it in one step with
#cipher_data = crypto.encrypt(src_data)
print('Encoded length', len(cipher_data))

# Convert the encrypted data to an image & display it
img = Image.frombytes("RGB", (size, size), cipher_data)
img.show()
img.save('redblue_AES.png')

# We need a fresh AES cipher object to do the decoding
crypto = AES.new(key, AES.MODE_CBC, iv)
decoded_data = crypto.decrypt(cipher_data)
print('Decoded length', len(decoded_data))

# Convert the decrypted data to an image & display it
img = Image.frombytes("RGB", (size, size), decoded_data)
img.show()
img.save('redblue.png')

以下是redblue.png和redblue_AES.png

redblue.png - the recovered original redblue_AES.png - the encrypted version