加密算法
背景:
现有的序列号加密算法大都是软件开发者自行设计的,大部分相当简单。有些算法,其作者虽 然下了很大的工夫,却往往达不到希望达到的效果。其实,有很多成熟的算法可以使用,特别是密 码学中一些强度比较高的算法,例如RSA 、BlowFish 、MD5等。对这些算法,网上有大量的源码或 编译好的库(当然这些库中可能会有一些漏洞),可以直接加以利用,我们要做的只是利用搜索引 擎找到它们并将它们嵌入自己的程序。应当指出,尽管这些算法的强度很高,但是使用方法也要得 当,否则效果就和普通的四则运算没有区别,很容易被解密者算出注册码或者写出注册机。
1.1 单向散列算法
单向散列函数算法也称 Hash(哈希)算法,是一种将任意长度的消息压缩到某一固定长度(消 息摘要)的函数(该过程不可逆)。Hash 函数可用于数字签名、消息的完整性检测、消息起源的认 证检测等。常见的散列算法有MD5 、SHA 、RIPE-MD 、HAVAL 、N-Hash等。
在软件的加密保护中, Hash 函数是经常用到的加密算法。但是,由于 Hash 函数为不可逆算 法,软件只能使用Hash 函数作为加密的一个中间步骤。例如,对用户名进行 Hash变换,再对这个 结果进行可逆的加密变换(例如对称密码),变换结果为注册码。从解密的角度来说, 一般不必了 解 Hash 函数的具体内容(变种算法除外),只要能识别出是何种 Hash 函数,就可以直接套用相关 算法的源码来实现。
1.1.1 MD5 算法
MD5 消息摘要算法(Mesage Digest Algorithm) 是由 R.Rivest 设计的。它对输入的任意长度的 消息进行运算,产生一个128位的消息摘要。近年来,随着穷举攻击和密码分析的发展,曾经应用 最为广泛的MD5算法已经不那么流行了。
1. 算法原理
(1)数据填充
填充消息使其长度与448模512同余(即长度=448 mod 512)。也就是说,填充后的消息长度 比512的倍数仅小64位。即使消息长度本身已经满足了上述长度要求也需要填充,填充方法是: 附一个1在消息后面,然后用0来填充,直到消息的长度与448模512同余。至少填充1位,至多 填充512位。
(2)添加长度
在上一步的结果之后附上64位的消息长度。如果填充前消息的长度大于2“,则只使用其低64 位。添加填充位和消息长度之后,最终消息的长度正好是512的整数倍。
令M[O…N-1]表示最终的消息,其中N 是16的倍数。
(3)初始化变量
用4个变量 (A 、B 、C 、D) 来计算消息摘要。这里的A 、B 、C 、D都是32位的寄存器。这些寄存器以下面的十六进制数来初始化:
A=01234567h,B=89abcdefh,C=fedcba98h,D=76543210h
而且,在内存中是以低字节在前的形式存储的,即如下格式。
0123456789 AB CD EF FE DC BA 9876543210
(4)数据处理
以512位分组为单位处理消息。首先定义4个辅助函数,每个都是以3个32位双字作为输入, 输出1个32位双字。
F(X,Y,Z)=(X&Y|((~X)&Z)
G(X,Y,Z)=(X&Z)|(Y&(~Z))
H(X,Y,Z)=XyZ
I(X,Y,Z)=Y^(X)(~Z))
其中,“&”是与操作,“|”是或操作,“~”是非操作,“^”是异或操作。
这4轮变换是对进人主循环的512位消息分组的16个32位字分别进行如下操作:将A、B、C、 D 的副本a、b、c、d 中的3个经F、G、H、I 运算后的结果与第4个相加,再加上32位字和一个 32位字的加法常数,并将所得之值循环左移若干位,最后将所得结果加上a 、b 、c 、d 之一,并回 送至A 、B 、C 、D, 由此完成一次循环。
所用的加法常数由表 TI1]来定义,其中 i 为 1 至64之中的值。7[i] 等于4294967296 乘以 abs(sin(①))所得结果的整数部分,其中i 用弧度来表示。这样做是为了通过正弦函数和幂函数来进一 步消除变换中的线性。
( 5 ) 输 出
当512位分组都运算完毕, A 、B 、C 、D 的级联将被输出为 MD5散列的结果。
以上是 MD5算法的简单描述。
( 5 ) 输 出
当512位分组都运算完毕, A 、B 、C 、D 的级联将被输出为 MD5散列的结果。
以上是 MD5算法的简单描述,更为详细的实现程序请参考随书文件中的源代码。
2.MD5 算法在加解密中的应用
MD5算法将任意长度的字符串变换成一个128位的大整数,而且是不可逆的。换句话说,即便 MD5算法的源代码满天飞,任何人都可以了解MD5算法,也绝对没有人可以将一个经 MD5算法加 密的字符串还原为原始的字符串。
在实际应用中,若单向散列算法运用不当,是没有什么保护效果的。看一看如下使用MD5 判 断注册码的伪码。
if(MD5 (用户名)==序列号)
正确的注册码;
else
错误的注册码;
正确的注册码以明文形式出现在内存中,因此,解密者很容易找到正确的注册码,注册机只要 识别出程序采用的是 MD5 算法就够了。遗憾的是,不少软件作者都偏爱这种判断注册码的方法。
MD5 代码的特点非常明显,跟踪时很容易发现。如果软件采用 MD5 算法,在初始化数据时必 然会用到上面提到的4个常数(A、B、C、D)。 实际上,像KANAL 这样的算法分析工具不是通过 这4个常数来鉴别MD5的,而是通过识别具有64个常量元素的表T 来判断是不是 MD5算法的。对 于变形的 MD5算法,常见的情况有3种: 一是改变初始化时用到的4个常数;二是改变填充的方法; 三是改变 Hash 变换的处理过程。在解密时,只要跟踪以上这些点,对MD5的源代码进行修改,就 可以实现相应的注册机制了。
1.1.2 SHA算法
安全散列算法 (Secure Hash Algorithm,SHA)包括 SHA-1 、SHA-256 、SHA-384 和 SHA-512, 共4种,分别产生160位、256位、384位和512位的散列值。下面以 SHA-1 为例,对 SHA系列散 列函数进行简要介绍。
1. 算法描述
SHA-1 是一种主流的散列加密算法,其设计基于和MD4 算法相同的原理,并且模仿了该算法。
SHA-1 算法的消息分组和填充方式与 MD5算法相同。
这与上面的f₁(B,C,D) 的定义是等价的,将产生相同的散列值。
类似于MD5,SHA-1 算法使用了一系列的常数 K(O),K(1),…,K(79), 以十六进制形式表示如下。
H₀=67452301h
H₁=EFCDAB89h
H₂=98BADCFEh
H₃=10325476h
H₄=C3D2E1FOh
解密者尝试分析算法时,可以通过上面的常数K,及 H, 来识别其为SHA-1 算法。
关于SHA-1 、SHA-256 、SHA-384 和 SHA-512 算法更加详细的计算过程,请参考 FIPS 180-1 及FIPS 180-2 。SHA-256 、SHA-384和 SHA-512 算法的初始化数据(十六进制形式)如下。
● SHA-256
6A09E667 BB67AE85 3C6EF372 A54FF53A
510E527F 9B05688C 1F83D9AB 5BE0CD19
● SHA-384
CBBB9D5DC1059ED8 629A292A367CD507
9159015A3070DD17 152FECD8F70E5939
67332667FFC00B31 8EB44A8768581511
DBOC2EOD64F98FA7 47B5481DBEFA4FA4
SHA-512
6A09E66713BCC908
3C6EF372FE94F82B
510E527FADE682D1
1F83D9ABFB41BD6BBB67AE8584CAA73B
A54FF53A5F1D36F1
9B05688C2B3E6C1F
5BE0CD19137E2179
1.1.3 SM3密码杂凑算法
SM3 是国密算法,由国家密码局发布。该算法广泛用于商用密码应用中的数字签名和验证、消 息认证码的生成与验证及随机数的生成,可满足多种密码应用的安全需求。经过填充和迭代压缩, 该算法能够对输入长度小于2“比特的消息生成长度为256比特的杂凑值。具体算法及运算示例参见 SM3算法标准