请求指导:从PNG提取图像数据、用OpenSSL加密并重构PNG
从PNG提取图像数据、加密并重构PNG的实操步骤
1. 提取原始像素数据(无元数据)
PNG的图像数据经过DEFLATE压缩,直接提取IDAT块还需解压,用ImageMagick的convert工具一步搞定最省心:
# 导出纯像素字节流,-depth指定位深(多数PNG为8位) convert tux.png -depth 8 tux.raw
如果需要确认原图像的核心参数(尺寸、通道数),用identify命令查看:
identify tux.png # 输出示例:tux.png PNG 320x320 320x320+0+0 8-bit sRGB 40960B 0.000u 0:00.000
生成的tux.raw就是不含任何元数据的原始像素字节流,顺序与原图像完全一致(比如RGBA或RGB通道顺序)。
如果想手动操作底层PNG块结构(不推荐新手尝试):
- 用
pngcheck -v tux.png查看IDAT块的起始偏移和字节长度 - 用
dd提取IDAT内容,再通过zlib-flate解压:
注:XXX和YYY需替换为dd if=tux.png skip=XXX count=YYY bs=1 | zlib-flate -uncompress > tux_uncompressed.rawpngcheck输出的对应数值,容易因计算错误导致失败。
2. 用OpenSSL执行加密(ECB/CBC模式)
ECB模式(你最初研究的模式)
ECB模式会让重复的像素块生成相同的加密结果,Tux图像的色块重复特征会非常明显:
# 生成16字节AES-128密钥(需AES-256则生成32字节) openssl rand 16 > key.bin # 加密,自动用PKCS#7填充补全到AES块大小(16字节) openssl enc -aes-128-ecb -in tux.raw -out tux_encrypted.raw -K $(xxd -p key.bin) -nosalt -padding
CBC模式(你提到的另一种模式)
CBC模式需要随机初始化向量(IV),不会出现ECB模式的重复块视觉问题:
# 生成密钥和IV(IV必须为16字节) openssl rand 16 > key.bin openssl rand 16 > iv.bin # 加密 openssl enc -aes-128-cbc -in tux.raw -out tux_encrypted.raw -K $(xxd -p key.bin) -iv $(xxd -p iv.bin) -nosalt -padding
3. 重构加密后的PNG
将加密后的字节流打包回PNG文件,必须严格匹配原图像的尺寸、通道数和位深:
# 示例:原图像为320x320 RGBA 8位深,按此参数生成PNG convert -size 320x320 -depth 8 rgba:tux_encrypted.raw tux_encrypted.png
若原图像为RGB通道,将命令中的rgba:替换为rgb:即可。
常见问题解决
- xxd查看PNG无意义:因为PNG的
IDAT块是压缩状态,直接看十六进制无法识别原始像素,必须先解压。 - 加密后图像出现多余像素:是PKCS#7填充的字节被当成了像素,可提前将原始数据裁剪为16字节的整数倍,或加密时添加
-nopad参数(但数据长度不匹配会直接报错)。 - 重构后图像花屏:大概率是
-size参数或通道类型(rgb/rgba)与原图像不匹配,重新用identify核对参数即可。
内容的提问来源于stack exchange,提问作者dmx
相关产品推荐
相关产品推荐

