初探无水印信息图片加密技术「建议收藏」

初探无水印信息图片加密技术「建议收藏」原文链接 https://yq.aliyun.com/articles/72267背景随着手机app越来越多,对于App信息安全面临的挑战越来越大,像接口传递的验证信息这些相对保密的信息如果直接放在app中明文,那么毫无疑问,很容易就被激活成功教程出来,想干嘛就干嘛。因为为了对部分本地信息加密,相处过无数的办法,本次讨论的重点,无水印信息图片加密。原理无水印信息图片加密,基

大家好,又见面了,我是你们的朋友全栈君。

原文链接 https://yq.aliyun.com/articles/72267

背景

随着手机app越来越多,对于App信息安全面临的挑战越来越大,像接口传递的验证信息这些相对保密的信息如果直接放在app中明文,那么毫无疑问,很容易就被激活成功教程出来,想干嘛就干嘛。因为为了对部分本地信息加密,相处过无数的办法,本次讨论的重点,无水印信息图片加密。


原理

无水印信息图片加密,基本原理,就是将信息负载在图片上,然后程序通过特定的算法将信息再度拿出来,而图片一看下去也是正常显示的,肉眼看不出任何的猫腻。那么到底怎么附加法?


1.追加信息法

利用不同格式图片的特性,例如BMP文件头标记了图片文件大小,后面信息不读取,或JPG文件拥有FFD9标志结束符,因此就算将再多信息附加上去,也不会影响原来图片查看。


2.颜色特征法

根据颜色的特点,因为颜色的最后一个位含有的信息量就算改变也不会改变大局,所以颜色的最后一个bit作为信息记录点。


3.颜色特征法Ex

颜色特征,按一定的算法,获取约定的图片特征,例如,都获取RGB中G的整张图的波形,通过某种滤波器,分析出来某段,然后加上校验码进行校验信息是否有效,而且多端,含冗余,分布图片各个地方,即使压缩,或者截图后,信息也有可能被获取到。


各自优缺点

追加信息法:

优点:

加密后图片正常显示,无信息长度限制,可以无限追加信息。我们都不明白为啥某个”正常”图片竟然有1,2G那么大,到底后面附加了什么?

缺点:

无限追加,也是致命缺点,你会傻到真的认为阿强那张1,2G的图片真的只是单纯的图片那么简单吧?


颜色特征法:

优点:

加密后图片正常显示,信息保密度更强,不会增加图片本身的大小,当然转格式例外,而且根据算法,整体的保密性更强。

缺点:

能加密的信息长度受图片size限制,如果对图片进行过压缩,信息将会损失的一塌糊涂。


颜色特征法Ex

优点:

经过压缩后,信息仍有机会提取出来,耐操,加密后不会改变图片大小,有冗余信息,激活成功教程难度大。

缺点:

图片容易显示不正常,当然搞成类似白噪点也是个技术活,能加密的信息的长度受图片size限制。


颜色特征法原理剖析

这里重点解释下颜色特征法是怎么实现的

颜色原理

说之前,必须要说下颜色的组成。大家都知道平时开发中我们使用的颜色值例如白色 #FFFFFFFF黑色#00000000 这些数字代表什么呢?


他们以2位16进制数字为一个单位分别代表A,R,G,B。记得在保存的时候别忘记了A,透明度,否则出来的都是黑色一片哦。

这里讨论R,G,B,他们代表红,绿,蓝,三原色。

而2位16进制的数字联合代表256个色值,换算2进制就是8位。因为主要决定颜色的信息其实都存储在这里,而前面的值表示颜色的变化越大,而最后以为相对改变的话,对颜色本身的影响是非常小的,255和254是相差很小的颜色变化。因为只要我们改变三原色随机一个或者几个的最后一位,其实对颜色变化影响微乎其微。肉眼根本不能看出变化。


int rgb = image.getPixel(curX, curY);

                r = (rgb & 0x00ff0000) >> 16;
                g = (rgb & 0x0000ff00) >> 8;
                b = (rgb & 0x000000ff);
                al = (rgb & 0xff000000) >> 24;

                if (bitLength >= 0) {
                    switch (iRGB) {
                        case 0:
                            r = (r & 0x000000FE);
                            r |= value;
                            break;
                        case 1:
                            g = (g & 0x000000FE);
                            g |= value;
                            break;
                        case 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 说明文件头开始到实际图片数据之间的偏移量,其实也是相对恒定的

位图信息头


变量名 大小 作用
biSize 4bytes BitmapInfoHeader结构需要的字数,固定的40
biWidth 4bytes 图像的宽度,用像素为单位
biHeight 4bytes 图像的高度,用像素为单位。还有个作用,标志图片是正向还是倒向的。如果该值是正数,说明图像是倒向的,如果该数是负数,那么图像是正向的
biPlanes 2bytes 为目标设备说明颜色的平面数,他的值总是设为1
biBitCount 2bytes 说明比特数/像数,其值为1、4、8、16、24、32,现在通常用24位
biCompression 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

未知.gif

后续:

这只是相对最简单的图像加密,图像并压缩后容易出现损失,因此,后面要加上特征值作为验证,还有应该有一定冗余,还需要部分对其做成类似噪点的研究。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/151998.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • Visual Studio 2010旗舰版正式版序列号

    Visual Studio 2010旗舰版正式版序列号用记事本打开:Setup–&gt;setup.sdb文件,将[ProductKey]YR3W8FCM2B7BKF9HMQFTCH7WK改成[ProductKey]YCFHQ9DW

  • 给“小白”图示讲解OFDM的原理

    给“小白”图示讲解OFDM的原理注:本文首发在QQ空间(因为需要同行的熟人们指正)。因QQ的封闭性,这里重贴一次。本文地址:http://blog.csdn.net/madongchunqiu/article/details/18614233  说明:以下文字,灰色为吹水文,黑色为正文,蓝色为采用实际应用中的参数所作的说明。  起因是这样的。时间回到07年底,4G方兴之时,同桌隔壁的隔壁”小白”同学说看不太明白OF…

  • 查询数据库空间使用情况的函数_查看当前数据库

    查询数据库空间使用情况的函数_查看当前数据库sp_spaceused[[@objname=]'objname'][,[@updateusage=]'updateusage'][@objname

  • 重庆java培训机构哪个好_java培训班

    重庆java培训机构哪个好_java培训班前言说到CAS(CompareAndSwap),不得不先说一说悲观锁和乐观锁,因为CAS是乐观锁思想的一种实现。悲观锁:总是很悲观的认为,每次拿数据都会有其他线程并发执行,所以每次都会进行加锁,用完之后释放锁,其他的线程才能拿到锁,进而拿到资源进行操作。java中的synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。乐观锁:总是很乐观认为,自己拿到数据操作的时候,没有其他线程来并发操作,等自己操作结束要更新数据时,判断自己对数据操作的期间有没有其他线程进行操作,如果有,则

  • java bufferedwriter 编码,Java BufferedWriter对象与utf-8

    java bufferedwriter 编码,Java BufferedWriter对象与utf-8IhavethefollowingcodeandIwanttomaketheoutputstreamuseutf-8.BasicallyIhavecharacterslikeéthatappearasésoitlookslikeanencodingissue.I’veseenlotsofexamplesthatuse…O…

  • 微信支付申请退款步骤_微信怎么没有退款提示

    微信支付申请退款步骤_微信怎么没有退款提示本文是【浅析微信支付】系列文章的第八篇,主要讲解商户如何处理微信申请退款、退款回调、查询退款接口,其中有一些坑的地方,会着重强调。浅析微信支付系列已经更新七篇了哟~,没有看过的朋友们可以看一下哦。

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号