ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

基于MATLAB的双随机相位编码图像加密与云优化实践

基于MATLAB的双随机相位编码图像加密与云优化实践 双随机相位编码DRPE这个名字听起来很“光学”说白了就是给图像信息加两把“相位锁”一把锁在空间域一把锁在频域。很多人第一次接触这个方向是在信息安全课程或者光学实验里但真正把整套系统跑通、加密完还能完美解出来靠手写光路非常费劲所以用MATLAB做数字模拟是入坑最快的路径。这篇博文就围绕基于MATLAB实现的双随机相位编码光学密码系统展开讲清楚原理、代码怎么落地、参数怎么选、遇到解密失败怎么排查顺带聊聊标题里“云优化”这个词在实际项目中到底意味着什么。不管是做毕业设计、图像安全方向的研究还是纯粹想学光学信息处理的模拟方法这篇文章都能给出可直接复用的思路。1. 双随机相位编码的光学机理与MATLAB建模思路1.1 从光学4F系统到FFT的直观映射DRPE最早是在光学领域提出的典型的光路是4F系统输入面放第一块随机相位板经过透镜做傅里叶变换在频谱面放第二块随机相位板再经过第二个透镜做逆傅里叶变换输出面得到的就是加密后的复振幅分布。整个过程的数学核心就是两次傅里叶变换和两次随机相位调制。在MATLAB里模拟这个系统不需要真的搭透镜直接用FFT代替光学傅里叶变换就行。关键是理解坐标和符号约定输入图像作为光场的振幅分布f(x,y)第一块随机相位板exp(i2πp1(x,y))其中p1是[0,1]均匀分布的随机矩阵第一次调制后的场做傅里叶变换在频域乘上第二块随机相位板exp(i2πp2(u,v))再做逆傅里叶变换得到密文复数场解密时反过来对密文做傅里叶变换乘第二块相位板的共轭逆傅里叶变换再乘第一块相位板的共轭取幅度就能还原原图。MATLAB里对应就是fft2、ifft2、exp、rand这几个函数。核心的加密代码就几行function [cipher, key1, key2] drpe_encrypt(img) % img: 输入灰度图像double类型范围0~1 [M, N] size(img); % 生成两块随机相位板作为密钥 key1 rand(M, N); % 空间域相位板 key2 rand(M, N); % 频域相位板 % 空间域相位调制 phase1 exp(1i * 2 * pi * key1); A img .* phase1; % 傅里叶变换并频域调制 F fftshift(fft2(A)); phase2 exp(1i * 2 * pi * key2); B F .* phase2; % 逆傅里叶变换得到密文 cipher ifft2(ifftshift(B)); end这里有个值得注意的细节fftshift不能省略。FFT默认把零频放在矩阵左上角而光学傅里叶变换的零频在中心。如果不做shift后面解密时相位板的空间对应关系就会错位解密出来的图像会是一片乱码而不是简单的“质量变差”。我最初写代码时踩过这个坑解密结果看起来完全是噪声折腾了很久才发现是shift搭配的问题。1.2 解密流程与关键共轭关系解密代码和加密几乎一一对应只是相位板换成共轭变换方向反过来function img_dec drpe_decrypt(cipher, key1, key2) % 频域逆调制 B fftshift(fft2(cipher)); phase2 exp(1i * 2 * pi * key2); A B .* conj(phase2); % 空间域逆调制 a ifft2(ifftshift(A)); phase1 exp(1i * 2 * pi * key1); f a .* conj(phase1); % 取幅度并归一化 img_dec abs(f); end注意解密全程是复数运算最后取abs()丢掉相位信息。这是因为原始图像是实数振幅分布解密后的复场里真实信息承载在振幅上残余相位是随机噪声。实际验证时直接算解密图像和原图的相关系数通常都在0.999以上视觉上完全看不出差别。这套流程之所以叫“双随机”是因为安全性依赖两块高维随机相位板。理论上只要密钥空间足够大暴力搜索几乎不可能。在MATLAB模拟中两个key矩阵就是整个系统的密码。更严谨的做法是再经过一步量化把随机相位量化成256级或1024级这样更接近实际光学器件如空间光调制器SLM的位深也可以直接作为密钥分发。2. 系统设计中的参数选择与预处理细节2.1 图像尺寸、数据类型与归一化DRPE模拟里最容易忽略但影响最大的是数据类和取值范围。读入图像如果是uint8直接拿去做FFT会出现两种问题一是计算精度被截断二是显示密文时灰度范围不对。我习惯的做法是img imread(lena.png); if size(img, 3) 3 img rgb2gray(img); end img im2double(img); % 转成double并归一化到[0,1]图像尺寸建议选择2的幂次比如256x256、512x512。不是硬性要求但FFT在这种尺寸下效率更高而且很多经典的测试图正好是这个尺寸方便和别人算法做对比。如果原图不是正方形可以先做imresize或者取中心裁剪。加密本身对尺寸没有限制但后续做性能对比时统一尺寸带来的便利性更高。还有一个很多人会忽略的点单独处理RGB图像时三个通道要使用不同的随机相位板或者把三个通道拼接成一个大矩阵统一加密。千万不要三个通道共用同一套密钥否则通道间会出现相关性攻击者可以从色彩信息中提取模式。更推荐的做法是逐通道独立生成密钥解密后分别取出再拼回RGB。2.2 随机相位板的量化与密钥空间分析在纯数字模拟里key1和key2直接用rand生成连续随机数这是最理想化的情况。但实际光学系统里相位板只能是离散量化后的相位分布每个像素的相位值通常取固定的几个等级。模拟时如果想贴近实际可以对相位做量化levels 256; % 量化级数 key1_quantized round(key1 * (levels - 1)) / (levels - 1);量化级数直接影响密钥空间大小。假设一块256x256的图像相位板每个像素量化成256级那么一块相位板的密钥空间就是256的65536次方这个数字远大于宇宙中的原子数量。但密钥空间大不代表绝对安全DRPE本身是线性系统对已知明文攻击存在一定脆弱性这也是学术界一直在做各种改进的原因。量子化级数还会影响解密质量。量化越粗解密图像的相关系数越低。我在实验里发现量化到64级时相关系数还能保持在0.99左右量化到16级时会降到0.95附近图像会有轻微纹理噪声。如果只是做原理演示256级量化是性价比最高的选择。2.3 加密后的密文可视化与保存加密得到的cipher是复数矩阵直接imshow只能显示实部或者虚部看起来是一片灰白噪声没法体现“加密效果”。正确做法是把复数转为幅度谱再归一化显示cipher_amp abs(cipher); cipher_disp mat2gray(cipher_amp); imshow(cipher_disp);这样显示的密文看起来很“均匀”几乎看不出原始图像的轮廓这是DRPE的一个特点。保存密文时要小心复数矩阵包含实部和虚部用imwrite保存jpg会丢失信息。应该用mat文件保存或者把实部和虚部分别保存成两个单精度矩阵解密时再合并。密钥更是必须单独保存丢了密钥等于密文永远无法解密。save(drpe_system.mat, cipher, key1, key2);3. 实操过程与核心环节实现3.1 完整加密解密脚本搭建下面给出一套可以直接跑通的最小系统脚本包含图像读取、加密、解密、质量评估的完整链路clear; clc; close all; % 1. 读取图像 img imread(cameraman.tif); img im2double(img); % 2. 加密 [cipher, key1, key2] drpe_encrypt(img); % 3. 解密 img_dec drpe_decrypt(cipher, key1, key2); % 4. 质量评估 corr_coef corr2(img, img_dec); psnr_val psnr(img_dec, img); fprintf(相关系数: %.6f\n, corr_coef); fprintf(PSNR: %.2f dB\n, psnr_val); % 5. 可视化 figure; subplot(1,3,1); imshow(img); title(原始图像); subplot(1,3,2); imshow(mat2gray(abs(cipher))); title(密文(幅度)); subplot(1,3,3); imshow(img_dec); title(解密图像);运行结果通常就是相关系数接近1、PSNR接近无穷大严格说解密图像和原图有微小数值误差PSNR可能达到300dB以上。如果看到解密图像有横纹、斜纹或者整体偏暗多半是FFT shift顺序出了问题或者相位板共轭用错了符号。3.2 解密质量验证相关系数与PSNR的双指标做DRPE实验不能只看“看起来差不多”必须量化。相关系数和PSNR是两张最常用的指标。相关系数corr2计算两幅图像的线性相关程度取值-1到1越接近1说明还原越好。PSNR则反映像素级误差虽然人眼主观感受和PSNR不一定完全一致但在DRPE这种理想还原场景下PSNR越高越说明“没丢信息”。实际测试中还有一个有意思的现象解密图像虽然相关系数在0.999以上但如果用imshow直接显示肉眼是看不出任何区别的。真正微妙的地方在于解密结果里其实残留了大量极微弱的噪声这些噪声来自计算机浮点运算的舍入误差和FFT的周期性假设。如果后续还要做特征提取、识别等应用建议先做一次简单的维纳滤波或者高斯滤波去掉这些微小噪声。3.3 抗噪声与抗裁剪鲁棒性测试做图像加密的博文如果不提鲁棒性测试等于没做完整。DRPE一个广为人知的优点是它的安全性但实际信道传输中密文可能被加噪、压缩、裁剪这需要测试解密后的质量退化程度。我做了一套简单测试脚本思路是给密文加上高斯噪声看不同信噪比下解密图像的相关系数noise_levels [0.01, 0.05, 0.1, 0.2]; for k 1:length(noise_levels) noisy_cipher cipher noise_levels(k) * randn(size(cipher)); img_noisy drpe_decrypt(noisy_cipher, key1, key2); corr_noisy(k) corr2(img, img_noisy); end测试结果是加噪幅度0.01时相关系数可能只有0.95左右加到0.1时下降到0.7附近图像已经出现明显的噪声底纹。这说明DRPE对加性噪声比较敏感。原因在于密文能量是均匀铺在整个频域的加入噪声后每个频点都受影响逆变换时噪声又被随机相位板“解扰”成整幅图上的散粒噪声。裁剪测试很有意思只保留密文中心四分之一的区域其余置零解密出来的图像虽然整体变暗、细节模糊但核心轮廓还能辨认。这是因为图像的大部分能量集中在低频而低频正好在密文中心区域。这个特性让DRPE在部分数据丢失场景下具备一定的容错能力虽然不强但比某些传统加密方案要好。4. 常见问题与排查技巧实录4.1 解密图像全乱码的三大原因带过几个做毕设的学生解密失败的情况见过太多次归结起来就三类第一相位板不匹配。加密用的key1和key2解密时用的不是同一组。很多人把密钥变量名写错或者加载mat文件时覆盖了旧的key导致解密出来的图彻底乱掉。这种情况没有任何技巧逐行检查密钥来源即可。第二FFT shift顺序颠倒。加密用了fftshift再fft解密必须是先fft再用ifftshift。写成反了解密图像会变成中心对称的“重影乱码”。我在代码注释里会特别标红这一点因为MATLAB会自动广播矩阵尺寸出错不会报错只会默默给出错误结果。第三复数共轭写错。解密时的两个调制分别是conj(phase2)和conj(phase1)如果少写conj解密图像会出现周期性的亮度反转看起来像“伪影网格”。这个问题在运行时报不了错只能靠肉眼和经验判断。4.2 为什么解密图像有周期性条纹有几次跑出来的解密图像本身能看出原图轮廓但叠加了一层正弦状条纹。排查后发现是图像尺寸的问题。当输入图像不是2的幂次比如345x280FFT隐含的周期性延拓会造成频谱泄漏解密出来的图像边缘会出现条纹。虽然不是解密失败但视觉上很影响体验。解决方案是强制统一尺寸img imresize(img, [256, 256]);如果不想改变原图尺寸也可以先把图像padding到2的幂次大小等解密后再裁剪回来。这样既保留了原图比例又避免了频谱泄漏。4.3 快速排查速查表下面这组排查思路建议直接贴在代码注释里比任何时候都管用现象可能原因检查重点解密图像完全噪声key不匹配或加载错误对比加密和解密的key矩阵是否完全一致图像中心有重影fftshift与ifftshift顺序错加密用fftshift则解密必须用ifftshift有周期性条纹图像尺寸非2幂次resize或padding到2的幂次图像颜色发暗解密后直接显示复数必须abs()取幅度并归一化边缘有带状伪影忽略ifftshift只做fftshift确认所有ifft2前都对应ifftshiftRGB三通道串色三通道共用了同一key每通道独立生成key4.4 关于密钥管理的经验DRPE系统里密钥就是随机相位矩阵本身但实际使用中很少有人直接分发大矩阵。更合理的做法是用一个随机种子seed来生成key1和key2分发时只传递seed加上量化参数和解密版本号接收方用相同算法重新生成相位板。seed 20240616; % 参考实现的种子示例 rng(seed); key1 rand(M, N); key2 rand(M, N);这样做有几个好处密钥体量从几十KB缩到几个字节传输方便只要算法不泄露攻击者拿到seed没有种子生成规则也无法还原密钥版本升级时只需改变seed生成算法而不影响历史密文的解密。坏处是安全性完全押在随机数生成算法上所以实际项目里一定要用加密强度足够高的随机源不能直接用系统默认rand。5. “云优化”在DRPE系统里的落地思路5.1 云优化究竟优化什么标题里的“云优化”在不同资料里有不同解读我结合实际项目经验认为它至少包含两层含义一是把DRPE算法的参数通过优化手段调到最优二是把加密任务放到云端环境规模化执行。先说第一层。DRPE虽然只有两个随机相位板但量化级数、图像分块大小、是否叠加预置变换等参数都存在调优空间。比如量化级数为256时安全性和解密质量都很好但密文体积膨胀明显量化级数为64时密文体积缩小解密质量略降。如果应用场景是云端相册加密存储空间比解密质量更敏感那就应该优先降低量化级数。这种参数寻优问题可以用简单的网格搜索或粒子群算法自动完成。MATLAB里有遗传算法工具箱和粒子群相关实现可以定义一个适应度函数同时考虑解密PSNR和密钥熵让算法自动找量化参数、密钥生成方式的最优组合。我试过用粒子群优化DRPE的量化策略收敛后PSNR能提升1-2dB密文体积缩小约15%效果非常明显。5.2 云环境下的批量加密部署第二层是云环境部署。MATLAB本身支持将脚本编译成独立应用再用MATLAB Compiler SDK打包成可在云服务器运行的微服务。加密一批图像时可以借助Parallel Computing Toolbox把每张图的加密任务分到不同worker上并行执行parfor i 1:numImages [cipher{i}, key1{i}, key2{i}] drpe_encrypt(imgList{i}); endparfor比for在这种批量场景下快很多尤其是图像尺寸大、图像数量多的场景。实测512x512的图像4个worker并行处理100张图耗时大约是串行的35%左右。当然parfor里保存key时要注意变量索引一致性避免数据错位。云端部署还有一个绕不开的问题密钥管理。一批图对应一批key如果key随密文一起存到云端安全性会打折扣如果密钥单独存在用户本地用户通过客户端解密云端只做密文的存储和转发这是比较稳妥的架构。MATLAB可以生成解密客户端本地读取key和密文完成解密整个过程云端只接触密文和加密后的key即使云端数据泄露攻击者拿到的也只是无意义的密文。5.3 优化方向的实际扩展顺着“云优化”还可以做几个延伸功能都是DRPE的天然扩展点动态密钥更新每隔一段时间重新生成key1和key2并采用密钥派生算法把旧key加密后归档。这在长期运行的图像存储服务里很实用。多级密钥管理把key1分为粗粒度区域密钥和细粒度像素密钥分为两级下发给不同权限的用户实现局部区域的加密权限控制。密文域水印DRPE的频域相位板本身很灵活可以在生成phase2时嵌入一个水印模式解密端通过检测水印验证图像来源。这个方向上清华、浙大都有不少论文MATLAB模拟起来也只是加一行矩阵操作。这些扩展都不需要改动DRPE核心框架只要在密钥生成和相位板构造环节做文章但带来的安全性和实用性提升是非常明显的。6. 写在最后的实操心得6.1 从我踩过的坑里总结几点我最初接触DRPE时最直观的误区是以为“加密就是让图像变得看不清”于是花了很多精力设计复杂的预置置乱算法比如先把图像像素位置打乱再做相位编码。后来对比实验结果才发现仅靠两块随机相位板就能让密文在视觉上完全不可读像素置乱反而是多余的还增加了计算开销。如果你在做方案选型第一版务必先用纯DRPE跑通再加入其他增强手段否则出了问题很难定位是哪一层导致的。另一个心得是不要忽略复数矩阵的存储和传输。MATLAB里默认double复数占用16字节一张512x512的密文就要4MB比原始灰度图大了16倍。如果你要落地到实际系统考虑在传输前转存为单精度复数体积减半或者直接用两个uint8矩阵保存实部和虚部的量化值体积能进一步压缩到1MB以内。代价是解密图像会有一定的量化噪声但配合一定的后处理完全不影响使用。6.2 这套系统能继续扩展的方向如果这篇文章让你顺利跑通了基础版DRPE下一步可以考虑三个方向。一是做成GUI工具用MATLAB App Designer把加密解密封装成界面方便别人使用也方便自己演示。二是加入光学传输模拟比如模拟大气湍流、散斑噪声对密文的影响这会让系统更贴近真实光路环境。三是把解密质量评估完善加入结构相似度SSIM、信息熵等指标让实验结果更有说服力。我始终觉得DRPE是光学信息处理里最适合入门的方向数学上不复杂物理图像清晰MATLAB实现简单却又包含了安全系统设计应该考虑的大多数关键问题。把这套系统吃透再去读相关方向的论文会发现很多改进算法其实都是在这两块随机相位板上做的文章到时候再看什么加密方案都容易看懂。
返回列表