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

初探无水印信息图片加密技术「建议收藏」原文链接 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

后续:

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

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

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

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Python 奇淫技巧 — 利用pandas读取xml转换为excel

    Python 奇淫技巧 — 利用pandas读取xml转换为excel因为工作需要,将xml中特定的节点值取出来,然后统计到excel中。于是乎试试写了一个python脚本,加快工作效率。而且今后还能复用。以下为完整示例,需要的朋友们可参考。示例XML<?xmlversion=”1.0″encoding=”utf-8″?><breakfast_menu><food><name>BelgianWaffles</name><price>$5.95

    2022年8月22日
  • tcp握手失败怎么办_TCP协议握手

    tcp握手失败怎么办_TCP协议握手大家好,我是小林。之前收到个读者的问题,对于TCP三次握手和四次挥手的一些疑问:第一次握手,如果客户端发送的SYN一直都传不到被服务器,那么客户端是一直重发SYN到永久吗?客户端停止重发SYN的时机是什么?第三次握手,如果服务器永远不会收到ACK,服务器就永远都留在Syn-Recv状态了吗?退出此状态的时机是什么?第三次挥手,如果客户端永远收不到FIN,ACK,客户端永远停留在Fin-Wait-2状态了吗?退出此状态时机是什么时候呢?第四次挥手,如果服务器永远收不到A

    2022年9月4日
  • resnet讲解_resnet50网络结构详解

    resnet讲解_resnet50网络结构详解1、 RestNet网络1.1、 RestNet网络结构ResNet在2015年被提出,在ImageNet比赛classification任务上获得第一名,因为它“简单与实用”并存,之后很多方法都建立在ResNet50或者ResNet101的基础上完成的,检测,分割,识别等领域里得到广泛的应用。它使用了一种连接方式叫做“shortcutconnection”,顾名思义,shortcut就是“…

    2022年10月7日
  • es6模板字符串_js循环字符串

    es6模板字符串_js循环字符串相比ES5的拼接字符串,ES6毫无疑问是简单明了,又清晰可维护。原始的字符串拼接真的是把整个人都拼傻,并且在处理的过程中会出现很多小坑,小问题。$(‘#ulList’).html(`&lt;ul&gt;&lt;li&gt;浙江&lt;/li&gt;&lt;li&gt;杭州&lt;/li&gt;&lt;/ul&gt;`);上面就是用es6的…

    2022年8月21日
  • CentOS7查看和关闭防火墙

    CentOS7.0默认使用的是firewall作为防火墙查看防火墙状态firewall-cmd–state停止firewallsystemctlstopfirewalld.service禁止firewall开机启动systemctldisablefirewalld.service转自:CentOS6和CentOS7防火墙的关闭关闭se…

    2022年4月4日
  • 成为java架构师需要具备那些技能?

    成为java架构师需要具备那些技能?架构师定义百度百科,系统架构师是一个既需要掌控整体又需要洞悉局部瓶颈并依据具体的业务场景给出解决方案的团队领导型人物。架构师工作职能软件架构师在整个软件开发过程中都起着重要的作用,并随着开发进程的推进而其职责或关注点不断地变化,在需求阶段,软件架构师主要负责理解和管理非功能性系统需求,比如软件的可维护性、性能、复用性、可靠性、有效性和可测试性等等,此外,架构师还要经常审查客户及市场人员

    2022年7月8日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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