原文链接https://yq.a liyun.com/articles/72267
背景
随着手机APP的增加,APP对信息安全的挑战越来越大。 界面传递的认证信息等比较保密的信息直接放入APP中制成明文,就可以很容易地被解读并想做的事情,这一点是毋庸置疑的。 因为为了加密部分本地信息,使用了无数的方法,所以这次讨论的重点是没有水印的信息图像的加密。
原理
无水印信息图像加密的基本原理是将信息加载到图像上,程序通过特定算法再次取出信息。 图像即使看也显示正常,肉眼看不见任何猫。 那么怎么追加法呢?
1 .附加信息法
利用在BMP文件的头部标记了图像文件尺寸,以后无法读取信息,在JPG文件中具有FFD9标志的终端代码等各种形式的图像的特性,即使添加了更多的信息也不影响原始图像的显示。
2 .彩色图案
根据颜色的特征,即使颜色的最后一个比特中包含的信息量改变,大局也不会改变,因此颜色的最后一个比特是信息记录点。
3 .彩色图案法Ex
颜色特征按照一定的算法,获取约定的图像特征。 例如,获得RGB中g的整个图像的波形,通过某种滤波器对某个段进行分析后,取校验码信息有效,且包含冗余,分布在图像的各处。 即使压缩、截图,也有可能获得信息。
优缺点
附加信息法:
优点:
加密的图像可以正常显示,没有信息长度的限制,可以无限添加信息。 我们不知道为什么某张“正常”的照片有1、2g那么大,到底后面附加了什么。
坏处:
无限添加,也是致命的缺点。 你真的傻到觉得ssdpd上那1、2g的图像真的只是单纯的图像吗?
颜色图案:
优点:
加密的图像可以正常显示,信息更敏感,图像本身的大小不会增加。 当然,转换格式是个例外,某些算法的整体机密性很高。
坏处:
可以加密的信息的长度受到图像size的限制,如果对图像压缩过度,信息会严重丢失。
彩色图案Ex
优点:
即使被压缩后,也有机会提取信息,操作性强,即使被加密,图像的大小也不会改变,有冗长的信息,很难解读。
坏处:
图像无法正常显示。 当然,让它像白噪声一样也是一项技术工作。 可以加密的信息的长度受到图像size的限制。
色彩轮廓原理分析
这里重点说明颜色特征法是如何实现的
颜色原理
在说之前,你必须说一下颜色的构成。 你知道我们在平时的开发中使用的颜色值,例如白#FFFFFFFF黑#00000000这个数字表示什么吗?
他们把2位的16进制数作为一个单位分别表示为a、r、g、b。 保存时请不要忘记a、透明度。 否则,出来的就是黑色的一张哦。
这里讨论r、g、b。 他们代表红、绿、蓝、三原色。
另一方面,2位16进制数字的组合表示256个色值,换算成2进制的话就变成8位。 主要决定颜色的信息其实保存在这里,但是之前的值是颜色变化越大,最后相对变化的话对颜色本身的影响就越小。 255和254是轻微的颜色变化。 因为只要改变三原色的随机的一个或几个最后的位数,实际上对颜色变化的影响就很小。 肉眼完全看不到变化。
intRGB=image.getpixel(curx,curY ); r=(RGB0x00ff0000 ) 16; g=(RGB0x0000ff00 ) 8; b=(RGB0x000000ff ); al=(RGB0xff000000 ) 24; if(bitlength=0)交换机(irgb ) case0:r=(r0x000000Fe ); r |=value; 布雷克; case1:g=(g0x000000Fe ); g |=value; 布雷克; 第2类
: b = (b & 0x000000FE); b |= value; break; } } rgb = al << 24 | (r << 16) | (g << 8) | b;
图片格式原理
如果你以为只是改个颜色值,就大功告成,呵呵,那你马上哭着发现,压根你加密的信息从来就没正确拿出来过。因为图片是含有头部信息的,而且不同格式的图片头信息肯定也不一致的,相对固定的头部是BMP图片的,因此俺们这次也是采用输出BMP图片作为加密后的结果图片。首先我们看看BMP文件头组成:
bmp文件头 变量名 大小 作用 bfType 2bytes 默认直接写死 424d 说明文件类型的 bfSize 4bytes 图片总大小,包括头信息 bfReserved1 2bytes 保留,必须设置为0 bfReserved2 2bytes 保留,必须设置为0 bfOffBits 4bytes 说明文件头开始到实际图片数据之间的偏移量,其实也是相对恒定的
位图信息头
0 表示不压缩
1 表示8比特编码,只用于8位图 biSizeImage 4bytes 图像大小,单位为字节 biXpelsPerMeter 4bytes 说明水平分辨率,像素/米 表示 biYPelsPerMeter 4bytes 说明垂直分辨率,像素/米 表示 biClrUsed 4bytes 说明位图实际使用的彩色表中的颜色索引数 biClrImportant 4bytes 说明对图像显示有重要影响的颜色索引的数目如果是0,表示都很重要
so,在修改完图片信息后,需要将这些信息补上头信息,再将颜色信息附上,关键代码如下补充头信息:
FileOutputStream fileos = new FileOutputStream(filename); // bmp文件头 int bfType = 0x4d42; long bfSize = 14 + 40 + bufferSize; int bfReserved1 = 0; int bfReserved2 = 0; long bfOffBits = 14 + 40; // 保存bmp文件头 writeWord(fileos, bfType); writeDword(fileos, bfSize); writeWord(fileos, bfReserved1); writeWord(fileos, bfReserved2); writeDword(fileos, bfOffBits); // bmp信息头 long biSize = 40L; long biWidth = nBmpWidth; long biHeight = nBmpHeight; int biPlanes = 1; int biBitCount = 24; long biCompression = 0L; long biSizeImage = 0L; long biXpelsPerMeter = 0L; long biYPelsPerMeter = 0L; long biClrUsed = 0L; long biClrImportant = 0L; // 保存bmp信息头 writeDword(fileos, biSize); writeLong(fileos, biWidth); writeLong(fileos, biHeight); writeWord(fileos, biPlanes); writeWord(fileos, biBitCount); writeDword(fileos, biCompression); writeDword(fileos, biSizeImage); writeLong(fileos, biXpelsPerMeter); writeLong(fileos, biYPelsPerMeter); writeDword(fileos, biClrUsed); writeDword(fileos, biClrImportant);
最后把图像信息也附上去。
for (int nCol = 0, nRealCol = nBmpHeight - 1; nCol < nBmpHeight; ++nCol, --nRealCol) for (int wRow = 0, wByteIdex = 0; wRow < nBmpWidth; wRow++, wByteIdex += 3) { int clr = bitmap.getPixel(wRow, nCol); bmpData[nRealCol * wWidth + wByteIdex] = (byte) Color.blue(clr); bmpData[nRealCol * wWidth + wByteIdex + 1] = (byte) Color.green(clr); bmpData[nRealCol * wWidth + wByteIdex + 2] = (byte) Color.red(clr); }
效果:
4350338-33116ce33bc6f997.gif
后续:
这只是相对最简单的图像加密,图像并压缩后容易出现损失,因此,后面要加上特征值作为验证,还有应该有一定冗余,还需要部分对其做成类似噪点的研究。