关键词:
动态图水印(精选四篇)
动态图水印 篇1
关键词:动态图,防篡改,中国剩余定理
0 引言
软件水印 (Software Watermarking) 技术是目前常用的软件保护技术之一, 它将版权信息和用户身份认证信息隐藏在软件中以达到证明版权的目的。近年来, 已经提出的软件水印算法有很多, 动态图水印 (CT算法) 是目前较有潜力的一种。水印算法的性能可以从隐藏信息量、隐密性和鲁棒性3方面衡量, 如何突破性能指标间的制约关系使整体性能有所改善, 无疑是个难题。
1 防篡改的动态图水印
1.1 动态图水印
Collberg和Thomborson提出了一种在程序执行过程中, 把软件水印隐藏在程序动态建立的图拓扑结构中的CT算法, 其基本思想是:用图的拓扑结构代表一个数N, 其中N是两个大素数P和Q的乘积。在进行水印检测时, 先根据图的拓扑结构恢复出N, 由于数论中的大数分解是困难问题, 只有合法用户才能将检测到的N分解成大素数P和Q的乘积, 从而证明其合法版权。
实验表明嵌入水印后的程序在性能上没有显著下降, 代码大小、执行时间和栈空间的使用都和原来相差不大, 而且这种水印能够抵抗大多数程序变换攻击, 具有良好的鲁棒性。
1.2 动态图水印编码
图拓扑结构的选取, 亦即水印数的表示方法的选取, 对于动态图水印系统的优劣来说是至关重要的。好的水印表示形式不仅对于攻击者来说难于分析其结构从而得出真实的水印信息, 而且可以尽可能少地带来宿主程序空间和时间上的过载。现有的动态图编码方案有基数编码、排列图编码、PPCT编码等。
1.3 基数和PPCT混合编码
对于不同编码方案的性能可以从比特率和纠错能力两方面来衡量, 基数编码具有较高的比特率但纠错能力较差;PPCT编码树与之相反, 每个叶节点的右指针都指向自身。通过叶节点的左指针可找到包含生成节点的循环链表, 由生成节点的右指针可得到整个PPCT及其对应的整数。因此它的比特率较低而纠错能力较强, 同时内部节点顺序的改变不影响编码结果。为了提高编码效率, 可将基数编码和PPCT结合起来, 编码方案如下: (1) 构造包含m个叶结点的二叉树B (根结点) , 并以m作为编码的基数, BT为其中一叶节点; (2) 表示水印的多项式中, 各项系数为叶结点的中序序号 (标于叶结点下方) , 指数为该叶结点中序遍历之后继结点的层序序号 (标于结点右边) 。
基数和PPCT混合编码如图1所示。
图1表示的大数为:44532=61×73=4×54+8×52+10×51+13×53+16×50+C, C=62。其中常量C既用于构造水印, 也为水印的防篡改提供用以编码的常量。
在以上几种基本的编码方法中, PPCT编码的抗攻击性能最令人满意, 所以其纠错能力最好, 但其编码效率较低;基数编码的编码率较高, 但抗攻击性能较差;混合编码方案兼顾了两者的优点。表1为基数编码、PPCT编码和混合编码的节点数与大数对应表。
由表1可以看出, 基数编码的编码范围大于PPCT编码, 而混合编码方案比PPCT的编码范围明显要大。其结构上的优点使其纠错能力和抗攻击性能相比基数编码有极大的提高。
2 基于中国剩余定理的动态图水印方案
2.1 中国剩余定理
定义两个符号并给出两个定义: (1) ZN:表示集合{0, 1, ……, N-1}; (2) [M]N:表示M除以N的余数, 且[M]N∈ZN。
定义1令p1
定义2如果p1
2.2 嵌入点的标识
嵌入水印之前, 需要仔细选择嵌入位置, 并用执行空操作的函数调用Mark () 标识出来。由于水印是由动态生成的水印图表示的, 因此应该在标识的位置上执行建立水印图的语句, 同时语句的执行直接依赖于用户的输入, 而且要设法避免水印嵌入在频繁执行的"热点"位置。总之, Mark () 位置上的水印代码应该是隐蔽的, 并且其执行仅依赖用户的输入。
2.3 标识点的追踪
并非所有的标识点都能够被追踪到, 在预定义输入序列k∈I下运行程序并形成有效标识点列表, 追踪不到或不恰当的标识点要移去。嵌入位置标识之后, 在预定义序列K下运行程序会追踪到一系列嵌入点, 并形成追踪点列表。这些嵌入点有些保留、有些要移去。有效的追踪点就是水印代码嵌入的位置。
2.4 水印嵌入
水印是通过隐藏信息的存在而达到版权保护的目的, 隐蔽性是水印的重要性能指标。现有提高水印隐蔽性的方法是先将索引值w对应的拓扑图G分解成n个子图G1, G2, …, Gn, 其拓扑图的分解采用了Kundu和Misra的水印图分割算法, 然后将子图G1, G2, …, Gn的构造代码嵌入在java程序中, 在运行时, 必须获得相应的密钥输入ki才会执行Gi的构建代码。分解时对水印子图有3个要求: (1) 各子图的大小基本一致; (2) 每个子图有一个根结点以便识别; (3) 各子图之间的连通边应尽量少, 提取水印时所需补充的边也最少。然而, 对拓扑图进行分割存在分割算法复杂度高、均匀分割困难的问题。因此, 本文提出了从分解水印图改为利用中国剩余定理分解水印信息的设计方案。
首先, 采用中国剩余定理将水印信息W分解成w1, w2, …, wn, 再将它们对应的拓扑图嵌入到程序的各个部分。实际嵌入程序的是分解后的水印编码, 每一个编码代表嵌入一个水印图。
2.5 水印数据的提取
水印数据的提取分3步, 如图3所示。
这里要强调的是, 必须保证每个水印子图都能正确提取并解码, 否则水印数据无法准确恢复。得到水印编码后, 由公式 (1) 恢复唯一确定的水印数据M。如果水印数据M超出机器字长, 应预先定义适当的数据结构 (如动态链表) 以正确保存恢复的水印数据。
3 算法实现
嵌入水印前的简单程序如下:
嵌入水印图后的水印程序:
嵌入的水印图如图4所示
当输入预定字符串"raorao"时, 进入if分支执行水印代码创建水印图, 同时将根结点n1保存在数组的第1个分量并作为方法P的参数进行传递。进行水印提取时首先判断水印图是否被篡改:未被篡改则继续水印的提取, 如果发现水印图被篡改, 则启动防篡改方案终止程序的运行。
4 性能分析
在假定的攻击模型下, 水印的性能从隐藏信息量、隐蔽性和鲁棒性3方面衡量, 且是3者的折衷;如果一个水印方案有效提高某方面性能, 或突破性能指标间的制约关系而使整体性能有所改善, 即认为该水印方案是对原水印方案性能的改进。
4.1 隐藏信息量
在几种基本的编码方法中, PPCT编码的抗攻击性能最令人满意, 所以其纠错能力最好, 但其编码效率较低;基数编码则由于其结构简单, 虽然编码率较高, 但抗攻击性能较差;混合编码方案兼顾了两者的优点, 不仅利用了PPCT编码方式的二叉树结构的稳定性, 而且利用了基数编码率高的特点。当然, 混合编码方案在提高编码率的同时, 也增加了检测时所需的时间开销, 只是这点时间开销的增加是有限的。
4.2 隐密性
水印技术通过隐藏秘密信息的存在达到版权保护的目的, 隐密性是水印的重要性能指标。本方案的隐密性体现在两个方面: (1) 大的水印数据分解为一组小的水印分量, 每个分量用独立的水印子图表示, 这样既可保证水印数据的大小不受物理限制, 同时各水印子图之间不存在连通问题; (2) 利用中国剩余定理分解和恢复水印数据, 可使水印数据突破机器字长的限制。
4.3 鲁棒性
本方案的鲁棒性体现在两个方面: (1) 水印图存储于动态建立的堆结构, 难以通过别名分析定位水印。因此, 本方案采用混合水印图表示水印, 可有效增强水印抵抗模式匹配攻击的能力; (2) 利用水印图的内部结构构造防篡改函数, 可以增加篡改程序或水印的难度, 同时一旦发生了被篡改能够即时感知并终止程序的运行。
5 结束语
本文提出的软件水印方案充分发挥了动态图水印的优势, 采取PPCT编码与基数编码混合编码的方法, 提高了编码效率和鲁棒性。同时根据水印性能指标间的制约关系, 提出了从分解水印图转变为利用中国剩余定理分解水印数据的思路, 使水印方案的隐蔽性和鲁棒性大为增强。
参考文献
[1]Nagra J, Thomborson C.Threading Software Watermarkings[C]//Proc.of the 6th International Workshop on Information Hiding, 2004.
[2]Moskowitz S A, Cooperman M.Method for Stega-cipher Protectionof Computer Code:US Patent, 1998.
[3]白雪梅, 凌捷.基于中国剩余定理的动态水印方案[J].计算机工程, 2006 (8) .
动态图水印 篇2
一般而言, 攻击者皆会选取程序输出分析、源代码分析、逆向工程、字代码分析、内存堆栈分析等途径攻击软件水印。相对于静态水印, 动态图水印免除了被混淆攻击的危险, 但动态图水印技术的安全系数并非为100%, 即动态图水印的结构节点有可能被拆分或删除等。
图一展示了动态图水印被攻击的几种情况。研究证实, 图示任一攻击形式均可造成动态图软件水印技术变得一文不值。基于此, 切实提高动态图水印技术的抗攻击性非常必要, 而增强其抗攻击性的真正价值是保护软件自身的价值, 进而实现软件抗攻击和软件抗盗版能力的增强。
二、基于多常量编码的动态图水印保护技术
1. 常量编码的选取
常量编码的选取流程如下:就水印程序予以词法分析→从若干编码常量内筛选出最佳常量编码→把选定的编码常量列入待编码常量列表。
2. 常量编码
常量编码函数要求用若干选定的待编码常量 (C1, C2, ……Ck) 来表达水印图的拓扑结构, 即以enCode (C1, Wn) , enCode (C2, Wm) , ……enCode (Ck, Wm) 来表示常量 (C1, C2, ……, Ck) ,
而en Code (Cj, Wm) 主要就Wm予以判断 (判断Wm的水印结构形式) 。若攻击者恶意篡改了水印结构, 则程序必然难以准确执行有关任务, 进而导致水印鲁棒性异常。基于多常量编码的动态图水印算法采用了PPCT结构、K基数循环链表结构、PPCT水印结构。
三、基于多常量编码的动态图软件水印算法的测量和评估
1. 数据率
就PPCT结构、K基数循环链表结构、PPCT水印结构而言, 若节点数目的最小值对应着自然数的最大值, 则可判定此水印结构的数据率最大。就如上四大水印结构而言, 若节点数目相同, K基数循环链表结构拥有最多的编码水印的节点数目, 则其亦拥有最高的数据率;PPCT结构拥有的数目最少。IPPCT结构属K基数循环链表结构和PPCT结构的结合体, 则其编码水印的节点数目大于PPCT结构且小于K基数循环链表结构。图二为K基数循环链表结构、PPCT结构、IPPCT结构的数据率曲线图。
2. 鲁棒性
测量和评估基于多常量编码的动态图水印算法依赖于基于动态图水印算法的水印系统, 而鲁棒性度量因子属水印系统鲁棒性的量化指标, 即鲁棒性度量因子的最大值对应水印系统抗攻击能力的最低状态, 而若上述两者的比值无限接近1, 其表明该水印系统的抗攻击能力最强。现把攻击模型定义为Java字节码混淆器, 即JBPOT, 并就水印嵌入程序做混淆攻击处理。表一列出了此次实验的部分数据。本文引入了5大测试程序就基于多常量编码的动态图水印算法的鲁棒性予以测试, 而以12次实验数据的均值为执行时间。
由上表可知, 基于动态图水印技术且被Java字节码混淆器混淆攻击后的IPPCT结构、PPCT结构和K基数循环链表结构可得, 其鲁棒性度量因子的最小值是1.01、最大值是1.14。由此可得, 基于动态图水印算法的水印系统的抗攻击性相当强。
四、结束语
综上所述, 基于多常量编码的动态图水印保护技术具有被攻击性, 但若保护技术的攻击成本超过了该技术的二次开发, 则该保护技术具备推广的价值。本文基于防篡改技术就动态图水印保护技术做了相应地阐释, 且引入了基于多常量编码的动态图水印算法和基于动态图水印算法的水印系统, 以此实现了动态图水印技术的抗攻击性和鲁棒性的提高。
参考文献
[1]Zhu Jiangtao, 程建华, Luo Yangxia等.基于多常量编码的动态图软件水印保护技术[J].计算机应用与软件, 2008, 25 (8) :59-61, 72.
一种基于防篡改的基数编码水印图 篇3
随着软件产品使用的日益普及,对其自身知识产权的保护也越来越多地引起人们的广泛关注。软件保护技术由此应运而生,其中包括软件加密、软件指纹、软件水印等。作为信息隐藏技术的一个重要分支,已有不少人开始了对软件水印的研究。对软件水印技术的分类,也有很多种,其中按提取方法分类可分为静态水印和动态水印[1,2]。静态水印具有生成和嵌入方便,提取较简单等特点,但容易受到各种不同类型的攻击,比如变形、追加和裁减等,而使提取水印可能失败。动态水印则是在程序的动态执行过程中,追踪指令或其地址的行为信息统计来提取水印或者构造特殊性的数据结构(动态图),如图、树或链表,并用其所蕴涵的拓扑属性来表示水印信息。目前较新的软件水印技术的研究大多都是围绕着动态水印。本文所讨论的内容,就是基于构造特殊的数据结构,即一种具有防篡改功能的基数K编码的软件动态数据结构水印方案。
1 现有主要的动态图软件水印编码方法
文献[3]提出了动态软件水印技术,即通过程序动态建立的图结构拓扑而把水印信息嵌入隐藏到软件中。由于指针的引用和别名分析难,构造水印信息的那部分代码不易加以分析,很难对其进行语义保持攻击。其基本思想是:用图的拓扑结构来代表一个大数n,即水印信息。该数可分解为两个素数P和Q的乘积,而只有版权所有者才知道这两个素数,利用大数分解难题,盗版者或攻击者即使能提取了N也很难对其进行分解。因此,能有效地提取大数N并对其分解,可用来声明其具有知识产权。现有主要的动态图拓扑结构的编码方法是:排列图编码,基数K链表编码,PPCT(Planted Plane Cubic Tree)枚举编码等。在排列图编码中,每个结点的入度和出度数都为2,抗攻击性能较好,但其编码效率一般。基数K编码的编码效率最高,但其抗攻击性能也最差。而PPCT枚举编码的编码效率最低,但其抗攻击性能最好。关于这几种编码方案更详尽的特点分析和比较,可参阅文献[1~5]。因此,若能充分地利用基数K编码的效率高,并对其抗攻击性加以改进,那么则可以得到一个较好的动态图软件水印方案。
2 防篡改的基数K编码动态图
2.1 基数K编码
基本的基数K编码是由k-1个结点的循环链表和一个头指针组成。其形式如图1所示。在基数K编码中,循环链表的每个结点具有两个指针域,其中右指针指向下一个结点,左指针用来编码,编码的数值为:
公式中,系数an值按下述给定规则确定:如结点的左指针为空,则an=0;结点的左指针指向自己,则an=1;结点的左指针指向下一个结点,则an=2;…;依此类推。如结点的左指针指向其前一个结点,则有an=K-1;如指向的是再向前一个结点,则an=K-2;…。
从基数K编码的特点可知,具有K个结点的链表形式可表示的数范围为0~Kk-1-1,相对于排列图(0~k!-1)及PPCT图(1/k×c2kk--12,其中结点数为2k)的编码范围而言,基数K编码在同等的给定结点个数情况下,其可表示的最大数最大。但从图1中也可看出:若某个结点的左指针或右指针发生指向转变;若删除或追加结点等遭受所谓的扭曲攻击或裁减、追加攻击,则图1不能够再表示原来的正确数值。因此,基数K编码的抗攻击能力较差。
2.2 防篡改的基数K编码
为了提高基数K编码的抗攻击能力,在其编码基础上引入防篡改方案,一旦遭篡改可即刻感知而终止程序的运行,从而保护了水印信息。关于防篡改的方法有很多,比如文献[4]中提出在静态水印中包含校验和的防篡改措施;还有一种代码水印防篡改的方法是检查代码本身,利用指令反射功能构造形如if(instruction#99!=“add”die())的语句等等。文献[5]中针对动态图水印提出一种称为常量编码的防篡改方案,即将程序中的部分常量置换为其值依赖于指向水印图的指针变量的函数;当水印被移去或修改时,函数值会随之改变而使被编码的常量值改变,最终导致程序错误或终止。在其文章中,主要是以PPCT图结构为水印信息,利用PPCT图内部蕴涵的相似结构来编码常量。虽然在防篡改方案上PPCT图没有额外的结点开销,但由于PPCT图本身在枚举编码水印信息时,所需结点数就较多,因此,相对而言编码效率不是太高。由于基数K编码的内部结构特性,使得很难采取和PPCT图一样的防篡改方法:即利用图内部蕴涵的相似结构来编码常量,即使能够找到相似结构,也很难对特定的常量值进行编码。究其原因,主要是基数K编码的系数和指数被编码在一个单链上,分支数不够多。另外,基数K编码的每个结点的度数不是恒定的值,故删除、或增加结点的边的篡改很难检测且对指针的扭曲攻击也较敏感。为此,本文提出在基数K编码图的基础上并结合PPCT图及排列的方法来形成防篡改的基数编码图。给出的编码方案如下:
为了方便描述,这里假设程序中需要编码水印数为N=82=2×40+0×41+1×42+1×43,展开式基数为4。编码的图示如图2,图2中主要由指数结点(编号为40,41,42,43的结点)、系数编码区(细横虚线箭头表示的区域)、路径(粗实线箭头表示的路径)等组成。具体编码方法如下:
(1)基本编码思想
根据水印数的基数形式展开式从每项小的系数值一直到大的系数值排列形成需编码的路径向量,若系数值为偶数,则对应的路径表示为1,若系数值为奇数,则对应的路径表示为0,如图2形成的路径向量为{1,1,0,0}。按照给出的路径向量来编码系数表示区和指数链表,具体是先生成最小指数的指数结点,若该指数对应的向量路径单元元素为1,则其对应的系数编码区用该指数结点的左指针形成,该指数结点的右指针形成下一个指数结点;若对应的向量路径单元元素为0,则其对应的系数编码区用该指数结点的右指针形成,该指数结点的左指针形成下一个指数结点。按照此种给定的方法用指定的路径向量表依此的形成后续项。形成路径的末端叶子由Origin生成结点的右指针指向来表示基数,从而基数值由图给出,图的表示是唯一的。当读取基数时以找到该叶子所经过的路径长度为基数。该基数叶的右指针指向系数编码区最右边的系数区,而某个系数编码区中排列最后的叶子右指针指向其次于右边的系数区,最后一个系数区排列的末端叶子指向Origin生成结点,且一个区内的叶子的左右指针在区内构成两个排列。如图2所示的按照基数为4来编码数N=82所最终形成的图样式,其中横—点虚线为区之间的连接。
(2)系数编码方法
考虑到编码的效率及防篡改的要求,我们知道PPCT图是目前在动态图水印中抗攻击表现最好的,因此,这里引入PPCT图样式来表示系数。但PPCT图在给定叶子结点数目下可枚举的数不是太多,如一个叶子结点的PPCT图,枚举的数范围为0;两个叶子结点的PPCT图,枚举的数范围为0;三个叶子结点的PPCT图,枚举的数范围为0,1;而n个叶子结点的PPCT图,枚举的数范围为1/n×c2nn--12。由于一个数的基数编码可能有多个系数,为了能够在防篡改基数编码图中表示更多的系数且所需结点数较少,规定按如下规则来编码系数:若系数值为0或1,则用一个叶结点的PPCT图样式表示,并分别用其位置在指数结点的左或右边来加以区分;若系数值为2、3、4、5、6、7、8、9时,则用两个叶结点的PPCT图样式表示,并对其内部叶子按照某种给定的次序加以编号(如从左至右层序优先遍历系数子树形成叶子编号),然后对叶子的左右指针串联某种要求的排列次序,不同排列对应不同的数字,并分别用其位置在指数结点的左或右边来表示不同的系数值含义。更大的系数值枚举依此类推。枚举系数的表示如图3所示。
枚举系数的计算公式如下:
其中,Xi(y)为按上述编码方法对拥有y个叶子的PPCT子图的第i个可编码的编码系数值;
IPPCT(y)为y个叶子的当前形状的PPCT索引值;
P(y)total为y个叶子的排列总数;
Pi(y)为y个叶子的右指针当前排列值;Pj(y)为y个叶子的左指针当前排列值;
k=0,表示系数图编码在左边,k=1,表示系数图编码在右边。
(3)防篡改方法
由于由此形成的水印图样式如同一个PPCT图,因此,在我们同样采用引入利用程序中定义的常量来进行常量编码,构成水印数和宿主程序的依赖性以达到防篡改。关于常量编码,有人提出通过构造多个相似的伪水印(每个伪水印对应一个常量)来迷惑的方案[6],若篡改者不加区分地加以篡改,则有可能篡改到常量的水印图,从而常量提取失败且程序执行不正确而终止。构造多个相似的伪水印其实是构造伪水印和真实水印的一种假的依赖关系,其最主要的特点是真实水印可在特定条件下才生成,而并不是程序在正常的执行下,形成真实水印的代码也得到执行。因此,该方法可增强真实水印的隐藏性,但真实水印一旦遭受到攻击,程序的常量提取可能依然正常进行,则对水印数的防篡改就无法实现。另一种方法是,在形成的真实水印图中寻找能够代表常量编码的水印子图。若真实水印图遭到破坏,则常量提取也可能失败,因此,该方法构造的是一种真的依赖关系。但其前提是程序在正常执行时,构造水印的代码也得到了执行,故其隐藏性较差,且一般情况下,水印图的每一个部分都要构造,这样可能引起宿主程序的额外执行开销较大。那么,在实际应用中我们可权衡两者的利弊,选择其中某一种来实施防篡改方案。对于第一种方法,我们可同样利用前述的防篡改基数编码方法构造多个相似的伪水印来达到防篡改。对于第二种方法,我们可先构造形成水印数的多个系数PPCT子图样式并将其编码成程序中的常量,并且可在一个给定条件下,按基数编码方法把多个系数水印子图合成一个真实的水印。
(4)小结
对于每一个给定的数,在给定的基数下都可以按照上述编码方法进行编码和防篡改。不过,应注意的是,若某个数的编码所需结点数较多时,我们可调整基数值来减少所需的结点数,即通过基数调整找到数表示的实际所需最少结点数。另外,在系数编码的区与区之间按照指定的要求来给以连接,且通过基数路径定位一个系数区后,该区内的叶子在排列时是连续指针连接在区内的,这样使得对系数编码区与区内部之间的结点相互指针扭曲或区自身的左右指针扭曲攻击都可能被检测到。而由于系数编码区内叶子结点的排列连接虽连续但无限制,则对内部自身结点的指针相互扭曲的检测可能失效,但相对来说其被扭曲而无法检测到的范围较整个可检测的范围小。为此,我们也可以使用散列函数对全部形成的系数值排列进行映射到等于基数位的某个随机值排列,然后使用该随机值对应的基数位排列来构造系数区与区之间的连接。检测时可采用一个守卫进程提取出区间的排列和系数值的排列并使用散列函数对系数值的排列求解,如得不到正确的区间的排列,则检测出可能已被篡改。
3 性能分析
由小结中可知,由于提供了对结点的扭曲攻击的检测方法很容易对结点的度的检测分析,并引入了常量编码等特点,因此相对于原有的基数编码图,其抗攻击力得到了增强。关于由此而来的额外开销,一方面,从上述的编码原理可知,一个N=82的数所需结点数为12个(基数K=4,包括一个Origin生成结点),而对于PPCT枚举编码,12个结点的PPCT图可枚举的最大数为41。因此,可知利用这种编码方法可使用较少的结点数来编码一个较大的数。而对于给定的m个结点,在基数为m/2-1时,其可编码的最大数为但是,用该种方法对给定范围的数进行编码时,并不是范围内的每个数都使用相同个数的结点数。为此,这里用编码某个范围内的数所使用的平均结点数来衡量其编码效率。我们使用的方法是表示的数对某个基数展开可能出现在系数位置上的系数值概率及对应系数值所需结点数进行加权平均来计算平均结点数。为了方便比较,这里采用和PPCT图进行了对比分析。分析结果如表1所示。从表1中可看出该编码方法所需最少结点数要少于PPCT。这里计算采用表示数字范围的基数作为基数,没有考虑实际可调整的基数。另外,我们对该方案进行了编程实践,并把其作为软件水印的研究工具Sandmark的插件进行实验分析,在实践中采取调整的基数为可表示数范围的基数浮动5个差值,虽然嵌入和提取水印计算时间较PPCT要稍大,但由于嵌入和提取的计算都是在被嵌入的软件外部进行,因此不会对嵌入的软件宿主自身运行造成同样的开销。经过对嵌入水印后的文件大小进行对比分析,发现和推测的结果较接近。而另一方面,相比于原有的基数编码图,编码效率虽有所下降,但由于自身结构的特点而使其抗攻击力得到了较显著的改善。
参考文献
[1]张立和,杨义先,钮心忻,等.软件水印综述[J].软件学报,2003,14(2):268-277.
[2]Zhu W,Thomborson C,Wang F Y.A survey of software watermarking[R].Lecture Notes in Computer Science-Volume,2002(3495):454-458.
[3]Collberg C,Thomborson C.Software watermarking:models and dynam-ic embeddings[C]//A iken A.Proceedings of the 26th Annual SIGP-LAN-AIGACT Symposium on Principles of Programming Languages(POPL'99).Association for Computing Machinery Press.1999:311-324.
[4]Holmes,K.Computer Software Protection[C]//US Patent 5,287,407.Assignee:International Business Machines,1994.
[5]Clark Thomborson,Jasvir Nagra,Ram Somaraju,et al.Tamper-proo-fing Software Watermarks[C]//Proc.Second Australasian InformationSecurity Workshop,ACS,CRPIT,2004,(32):27-36.
动态软件水印的研究与实现 篇4
关键词:版权保护,软件水印,动态水印技术,保护策略
0引言
随着Internet的日益普及,数字产品几乎渗透了工业、商业、人类日常生活等方方面面。尤其是软件产品,由于其复制简单,传播速度快,且复制成本低廉等特点,由非授权使用和恶意盗用而引起的产权纠纷也随之日趋增多,软件产品的保护逐渐成为人们亟待解决的关键问题。软件水印就是在这种迫切需求下发展起来的新技术。通过在软件产品中嵌入的水印信息来确定版权所有的软件水印技术,弥补了加密技术不能对解密后的软件提供进一步保护的不足,为软件版权保护提供了一种新的思路[1]。
作为数字水印技术的一个重要分支,软件水印技术的研究尚处于起步阶段。在软件水印的研究领域,诸多研究者已经取得一些成果,文献[2,3,4]对国内外的研究现状做了比较全面的介绍与分析。然而,这些研究主要集中在水印理论的完善及算法的改进上,而实际的应用研究不容乐观,且很少涉及实现细节。
本文基于C#.NET框架实现了一个维、汉双语记事本软件。在研究了软件水印相关概念及其实现原理的基础上,从软件水印应用的角度出发,采用动态软件水印技术并结合一定的安全策略,实现对该记事本软件的版权保护。具体通过将水印信息嵌入到记事本软件中,一旦发生版权纠纷,可通过提取水印来验证版权的拥有者。
1软件水印相关概念
软件水印技术将一些标志性的机密信息嵌入到被保护的软件中,用于标识发行者、所有者、使用者等与版权密切相关的信息[2,3]。软件水印主要用于软件的版权保护,使得它们免于非法的拷贝与盗用。当软件产生版权纠纷时,软件水印可作为一种证据,所有者可以通过提取事先嵌入在软件中的水印信息确认真正的版权拥有者,从而起到保护版权的作用。
1.1软件水印的分类
软件水印有多种分类方式,可根据水印的可见性、水印使用目的、水印被加载的时刻及水印加载的位置等对软件水印进行分类。其中具有代表性的是按照水印被加载时刻的不同将软件水印分为静态水印和动态水印[5,6,7]。下面简单介绍几种软件水印的特点。
(1) 静态水印
静态水印存储在可执行应用程序本身当中,它的存在不依赖于软件的运行状态。根据水印的存放位置,静态水印又可进一步分成静态代码水印和静态数据水印。
通常将静态代码水印隐藏在可执行代码中,甚至存放在说明中。而静态数据水印存放在其它区域,包括头文件、字符串中或调试信息等。
(2) 动态水印
动态水印的存在依赖于软件的运行状态,其生成一般需要通过某种特殊的输入条件来触发,其验证也必须在这类特定时机才可完成。根据水印产生的时机和位置可将其分为三类: Easter Egg水印、动态数据结构水印和动态执行序列水印。
Easter Egg水印接受某种特殊输入时,会产生一些具有特定意义的输出。动态数据结构水印将水印信息隐藏在堆、栈或全局变量域等程序状态中,并通过检测程序变量的当前值来进行水印信息提取。动态执行序列水印,在接收特殊的输入触发后,对程序中指令的执行顺序或内存地址进行编码生成水印,水印的检测则通过控制地址和操作码顺序的统计特性来实现。
文献[3,7]均提到静态水印虽然生成方式灵活多样,而验证方便、快速,但它很容易被攻击者发现存放的位置。针对静态水印的攻击一般直接采用一些自动化攻击,比如Profiling攻击、指令乱序攻击或统计分析攻击等。和静态水印相比,动态水印存储在程序的可执行状态中而非程序代码本身,这使得它本身具有一定的防篡改功能。
1.2软件水印的实现原理
软件水印的实现主要包括水印信息的嵌入和提取两个过程[8]。在嵌入阶段,对于给定的应用软件P,利用密钥Key对软件版权信息W进行加密,并通过特定的机制将加密后的密文信息W’作为水印内容嵌入到P中,形成隐含水印信息的软件PW’。
水印的提取过程是嵌入过程的逆过程。一旦发生软件版权纠纷,在Key及辅助信息(P、W及其它相关信息)的协助下将水印信息W’从PW’中提取出来,并对其进行解密处理,从而声明软件版权。为了更加深入地理解软件水印的基本原理和特点,图1给出了软件水印的嵌入和提取过程。
1.3软件的保护策略
由于绝大多数的软件水印经不起反编译或逆向工程等攻击,使得其鲁棒性并不是那么理想。无论是静态水印还是动态水印,没有一种水印技术方案能够抵抗所有的攻击[9]。单靠软件水印很难做到对软件的真正保护,目前很少有商用系统会单纯采用某种软件水印方案。因此多种软件保护技术相结合,是提高软件水印的健壮性,增强水印的版权证明能力的重要手段,也是目前软件水印的主要发展趋势[10]。
目前,软件产品所面临的威胁主要源于三个方面:软件盗版、逆向工程和恶意篡改。针对这三方面的攻击,相应的保护手段包括防盗版技术的软件水印技术、防逆向工程的代码混淆技术、以及防恶意篡改的软件防篡改技术等[6]。为了弥补软件水印的不足,提高其鲁棒性,本文将软件水印与混淆技术相结合,在对软件版权保护的同时,利用混淆技术尽可能地增加逆向工程的难度,提高软件的安全性。
代码混淆其实是一种转换技术,它采用特定的混淆策略对应用程序进行转换,使得混淆变换后的程序和原来的程序具有相同或相近的功能,而混淆后的程序较原始程序更加难以理解[11,12]。混淆变换的原理如图2所示。
在对应用程序进行混淆处理之前,首先确定需要进行混淆处理的对象,其次明确要对应用程序进行怎样的转换,最后就是对应用程序要进行几次转换。被混淆处理的对象都是在进行混淆处理之前由用户选择好的,用户根据自己需求进行选择,例如:用户可以对整个应用程序进行混淆,异或选择其中的几个类,或者某些变量进行混淆处理。一般情况下并不选择对整个应用程序进行混淆处理,以避免对程序的性能产生太大的影响[13]。
2软件水印实现
借鉴微软公司的记事本功能我们开发了一个维吾尔语、汉语(维、汉)双语记事本软件。为了对其版权实施保护,根据上述软件水印的实现原理,结合相关的软件保护手段,探索一种动态软件水印版权保护措施。随后将通过实例阐述软件水印的具体实现过程。
2.1记事本软件的设计与实现
本文在Visual Studio. NET环境下用C#编程语言,实现了一个维、汉双语记事本软件。该软件与Windows操作系统自带的记事本应用程序功能基本相同,主要包括文件、编辑、格式、查看等菜单。其特色之处在于实现基本的记事本功能的同时,该软件也支持维吾尔语输入,提供良好的维汉双语界面,如图3所示。
2.2嵌入水印信息的实现
实现了记事本软件的设计后,下面将重点介绍软件水印在该记事本软件中的嵌入过程。
(1) 确定水印信息W
按1.2节中软件水印的实现原理,水印嵌入阶段的第一步须确定软件的水印信息,即W。当前软件的水印信息内容主要包括开发商:###;开发者:###;开发日期:###;版本:###;版权号:###。除此之外,开发者可以根据不同需求制定特定的水印信息。
(2) 加密处理
对于无密钥的软件水印,水印信息的安全性完全依赖于隐藏和提取算法的保密性。因此为了防止攻击者截获水印信息内容,可以选择不同的加密算法对水印信息进行加密,实现对水印信息的保护。本文采用一定的加密算法对上述水印信息进行加密,加密后的水印信息W’分散在图4-图6中,以十六进制的字符串表示。
(3) 嵌入水印信息W’
将加密后的水印信息W’ 分为n个片段嵌入到记事本的源代码中。每一个片段将加密后的部分水印信息赋给当前记事本软件中所定义的结构体的相应变量中;每一个赋值过程均由不同的事件触发来完成,如水印信息W’的第一部分是由文本改变事件触发完成,第二部分是由记事本加载事件触发完成,第三部分则是在记事本程序中按下回车键时触发,其它水印片段的嵌入不在这里赘述。实现这三部分工作的相应代码如图4-图6所示。
由代码不难看出,无论是“文本发生改变”、“按下回车”、还是“记事本运行”,它们都是记事本软件的基本操作,只要使用该记事本,相应的水印信息就会不经意间自动加载到软件中,不需要其他特殊操作。为了安全起见, 代码演示中的水印内容和相应的变量都经过转换,并不是真实的数据。
2.3水印信息的安全性分析
值得注意的是,在软件水印的嵌入过程中,水印信息得到加密保护,即使非法使用者通过一些逆向工程或反编译等技术攻击软件,即使发现了软件中的版权信息,也不易判断信息的具体内容。经过加密处理后的信息降低了其被破解的可能性,进一步提高了记事本软件版权的安全性。
同时,为了提高软件水印的安全性,在嵌入软件水印信息时采用了一些安全策略,通过一些基本的代码混淆技术将水印信息嵌入到代码中。将加密后的水印信息W’分成n个片段分别散列在软件源代码的不同位置。当且仅当n个部分全部触发完成后,与记事本软件版权保护有关的信息才会被完整地赋值。这使得整体代码不易理解,要检测到所有的水印信息需要花费一些时间。只有当攻击者将全部水印片段拼接起来,经过解密才能获得全部版权。由此可见,本文将攻击者的风险分摊在n个子组件中,使得原本破译一次就可获取全部版权成为不可能,为攻击者的逆向工程工作设下了一定的障碍,大大降低了软件版权被破解的风险,提高了软件版权的保护程度。
除此之外,论文还对一些变量进行混淆,使得攻击者不易理解变量的命名。例如代码实现时,为了使得代码易于理解一般采用一些直观的命名方式。例如为了保护软件的版权,我们需要对记事本软件的开发商、开发者等水印信息相对应的变量进行转换,混淆其直观上的意义使其不易理解。并对一些具有继承关系的类进行合并处理。针对给定的原始类Cl、C2,进行合并处理生成目标类C。
2.4水印信息的提取
提取水印信息的过程也即水印信息的自检测过程,目的是通过提取出的水印信息验证是否与最初添加的水印信息相一致。如果两者完全吻合,说明水印信息没有被篡改;如果两者不完全吻合,则说明水印信息可能被修改过,从而保证水印信息的完整性。自检测也需要触发条件,一旦触发条件满足便执行一段可执行代码,水印信息便通过自检测过程提取出来。
(1) 提取水印信息W’
提取水印信息时,首先必须确保源代码中确实隐藏了相应的水印信息。其次需要满足特定的输入来触发代码的运行。具体实现是在记事本中输入特定的字符串,如“#abc^def#”。当输入完成后,按下Enter键触发水印信息片段的组合过程。此时,记事本软件将检测到的加密后的水印信息整合并提取到相应的文本文件中,检测出来的水印信息仍然显示为只包含十六进制的字符串。相应的检测代码与水印信息均写在目标程序的代码中的不同位置。
(2) 解密处理
解密是通过加密算法的逆运算来实现。本文采用与加密算法相对应的密钥对加密后的水印信息进行解密,以验证其是否被篡改。如图7所示,通过对应的解密算法对txt形式提取出来的加密后的水印信息进行解密,获得真正的水印信息。
(3) 软件水印的验证
将解密处理后的水印信息与原水印信息W进行比较以验证该水印是否被篡改。从图7中可以看出,解密后的水印信息与原始水印信息完全吻合,从而验证了该软件的版本所有者。
3结语
本文研究了动态软件水印技术,结合加密技术和代码混淆技术,针对一个维、汉双语的记事本软件刻画了水印的嵌入过程。为了验证水印信息的完整性,还将此水印信息提取并解密后,与原始水印信息进行对比。结果表明,本文所完成的工作可以很好地实现软件版权信息的保护。下一步的工作将在本文研究与实现的基础上引入软件防篡改技术,探索更理想的版权保护方法。
相关文章:
数字水印算法技术01-03
数字水印算法分析论文01-03
数字模型水印01-03
数字水印技术:概念、应用及现状01-03
水印图像01-03
小升初自我介绍模版无水印01-03
数字水印嵌入01-03
数字水印技术及其应用01-03
多功能音频水印01-03
零水印算法01-03