如何从PNG图像中获取像素数据以进行gpg签名?

时间:2015-07-31 02:58:24

标签: python serialization pickle

我想要gpg - 将像素数据设置为PNG图像。后来,我希望能够gpg - 验证像素数据上的签名,以了解图像的作者,并且自签名以来它没有改变。

动机

我正在开发一个系统,可以在以后验证和归因(参见不可否认性)PNG图像的完整性。我在Python工作。理想情况下,我希望附加信息不会妨碍任何用户像往常一样阅读图像。

图像中有什么重要的?在我的应用程序中,只有像素数据很重要。我需要将这些数据转换为gpg --sign接受的形式,这相当于序列化Python对象。在未来被篡改的图像中验证签名的能力依赖于序列化(pickle.dumps,cPickle.dumps)产生相同的输出,比如说从现在起5年。

为什么不用gpg -sign签名文件?将像素数据的签名粘贴回相同图像的元数据中使签名1.附加并且2.有效。在图像的任何地方,签名都是如此(除了可能会删除它的任何过度热心的软件)。

以下示例旨在在ipython中运行。

签署PNG图像。

# The PNG image to sign.
f = 'image.png'

# Read pixel data from a PNG image.
from pillow import Image
serialized = Image.open(f).tobytes(encoder_name='raw')

open('serialized.txt').write(pixel_data)

# Sign the data with gpg using the default private key.
!gpg --sign --detach --armor --output sig.asc serialized.txt
# <enter gpg passphrase as required>

# Write the signature to the PNG image's metadata using Image Magick.
import subprocess
subprocess.call(['mogrify', '-set', 'gpgsig', open('sig.asc').read()])

# Verify it got added using Image Magick.
!identify -verbose image.png

很久以后,尝试验证签名

# Many, many moons go by, and you find a PNG image in the wild.
# It looks familiar, but its provenance and integrity are unknown.
# But lo! it includes a gpg signature in its metadata.
# You want to verify the signature (which may have been signed
# by yourself or anybody else whose gpg public key you have
# access to) to ensure the image is unchanged.

# Read the pixel data, same as before.
from pillow import Image
serialized = Image.open(f).tobytes(encoder_name='raw')

open('serialized.txt').write(serialized)

# Get the included signature.  This may be done
# programmatically, but for the sake of simplicity,
# just use Image Magick.
!identify -verbose image.png

# Save the signature to sig.txt.

# Attempt to verify the detached signature
!gpg --verify sig.txt serialized.txt

1 个答案:

答案 0 :(得分:1)

我想用pycrypto在内存中签名来哈希并签名,我想。序列化是一个非常必要的额外步骤。

编辑:这是以前的问答:

Signing and verifying data using pycrypto (RSA)

在阅读下面的评论后编辑两个:

我相信PIL tostring()函数只是将像素数据转储成字符串,例如它是预先序列化的。因此,如果您真的想使用外部程序,也许您只需将此字符串输出到文件即可。