• 标 题:一个菜鸟对密码学的理解 (4千字)
  • 作 者:RoBa
  • 时 间:2003-10-22 13:45:12
  • 链 接:http://bbs.pediy.com

前言:

就在菜鸟们正为破了一个明码比较的软件而欢欣鼓舞时,各位大大都在研究密码学了,本菜鸟我也不自量力地紧跟其后,怎奈各种介绍密码学的书都太专业了,而且不是针对CRACK的.一上来就是一堆公钥,私钥,HASH之类的东东,大概不少菜鸟一看到这些都被吓回去了.这里我把密码学在软件加密上的大体思路向各位菜鸟同胞们介绍一下.如果你是菜鸟,你会发现,密码学不是你想象中的那么难;如果你是大侠,最好跳过这篇文章,不然就要把大牙捂好,当心笑掉了. :)

好了,废话少说,我先来讲讲软件加密中的基本思想.

我们知道,不管形式怎样复杂,各种共享软件都是把用户名和注册码经过一定的计算后进行比较.现在假设有一个软件,作者采用的注册算法是把注册名的每一位都+1而得到注册码(当然实际中不可能这么简单).我是一个用户,我想注册这个软件,于是我把我的名字RoBa和SOME MONEY给作者送去,作者那里肯定有一个注册机的,作者的注册机经过计算('R'+1='S','o'+1='p','B'+1='C','a'+1='b')后把注册码SpCb发给我,然后我把用户名RoBa注册码SpCb输入软件中,点击"OK",这时候软件该怎么办呢?如何进行注册判断才安全呢?

一种很常见的方法是,软件把用户名经过计算后与注册码比较,也就是判断
if 注册码==F(用户名) then 成功 else 失败
现在我是Cracker,我不想给作者MONEY,那么我跟踪这个软件,输入用户名RoBa,假码5678,然后可以发现,它把'R'+1,把'o'+1,把'B'+1,把'a'+1,再把结果'SpCb'组合起来与'5678'进行比较.也就是说,软件实际上把作者手里的注册机的功能再现了一遍,其实这个软件本身就包含一个注册机,破解者甚至不必看懂注册算法,只要把软件中计算注册码的那一部分提取出来就是注册机了.这显然是非常不安全的,一些CRACK初学者只要到处乱D,就可能把注册码D出来(我以前经常这样做^_^).

那么正确的做法应该怎样呢?我假设仍然是这个注册算法,作者手中的注册机也不变,只是要把软件中判断注册的部分变一下.不去根据用户名计算注册码,而是根据注册码反算用户名,即
if 用户名==F'(注册码) then 成功 else 失败
我又来跟踪这个软件了,输入用户名RoBa,假码5678,然后开始跟踪,结果发现软件计算'5'-1,'6'-1,'7'-1,'8'-1,然后把结果'4567'与'RoBa'比较,这样就给人一种莫名其妙的感觉.如果我是一个初学者,我会在内存中发现一个字串'4567',但这个字串却不是用户名RoBa所对应的正确注册码,这样就防止软件被破解和写出注册机.当然在上面这种情况下我可以在用户名输入'4567',然后在注册码输入'5678',但这样会给人的感觉很不爽,而且大多数情况下胡乱输入的假码经过反算后得到的用户名含有不可显示字符,这样就给破解带来了麻烦.

还有一点是非常需要注意的,采用第二种方法时,注册算法必须是可逆的,也就是说作者必须有方法通过用户名算出注册码来,而软件也必须能通过注册码算出注册名.

各位菜鸟同志可能有疑问了,这样只是不让初学者把注册码乱D出来,如果遇上高手呢,软件中那个减1的运算不是很容易就会被识破吗?所以说,这时候我们的密码学就派上用场了.(终于来到正题了*_*)

下面我把三类常见的加密算法介绍一下: (按看雪书上的顺序)

(一)单向散列算法,也叫Hash算法

呵呵,别被这个名字吓住哦!其实说通俗一些,就是把一个字串A乱七八糟计算一通,得到一个乱七八糟的字串B,不管你有多大本事,你也不可能从字串B反算出原来字串A,也就是说是一个不可逆的计算.
各位可能又问了,你前边说了半天注册算法必须可逆,这种不可逆的计算有什么用呢?完全正确,这种算法在软件注册中其实并没有什么实际作用,最多只是作为一个中间过程而己,所以不详细介绍了.

这一类的常见算法:MD5,SHA等

(二)非对称算法

根据前面所讲的,软件的计算实际上是两个互逆的运算:
在作者的注册机上计算: F(用户名),在上面的例子中即为 注册码=用户名+1   (计算1)
在发布的软件中计算:  F'(注册码),在上面的例子中即为 用户名=注册码-1   (计算2)
CRACKER只能得到计算2,但是在一般的可逆计算中,通过计算2可以很容易用数学知识求出计算1,比方上面的例子,有小学数学知识的人就会吧?只要把计算1研究出来,注册机也就写成了.

那么有没有虽然存在逆运算但不能被随意求逆的算法呢?这就是非对称算法了.
这种算法是可逆的,但它的计算有点特别,需要两个关键的KEY(密钥),而且这两个KEY不同,如果没有KEY就无法计算.软件作者经过一定的规则设定这两个KEY,然后用下面的方法:
作者的注册机上: 注册码=F(用户名,KEY1)
发布的软件中:   用户名=F'(注册码,KEY2)
这样CRACKER跟踪时可以发现KEY2,也知道用户名是怎样计算出来的,但他不知道KEY1,无法把这个运算逆回去,很奇妙吧?这里面有许多高等数学中数论的知识,各位可以研究一下.(不要来找我,我高中还没毕业 :))
这样的算法怎样破解呢?虽然KEY1和KEY2不同,但它们是有一定的关系的,只是这样的关系很难求解(比如大数分解等一些数学上的难题),如果KEY设计得足够大,由KEY2求出KEY1几乎是不可能的.但因为算法要用在注册判断上,如果KEY太大的话要浪费很多时间,在实际中不可取,所以这就给我们CRACKER提供了机会,用相应的工具可以在较短的时间间由KEY2解出KEY1来,从而写出注册机.

这一类的常见的算法有RSA,ECC等

(三)对称算法

对称算法和上面的非对称算法最大的不同就是两个关键的KEY是相同的,这样的算法用在通信上当然没有问题,但在软件加密上就很不安全了,因为你发布的软件中要进行解密运算,必定会包括这个KEY,而软件只要在别人的机器上运行,软件中包含的一切对高手来讲都没有安全性可言,这个KEY一旦被跟踪出来,软件就被破解了.

这一类的常见算法有BlowFish等

后记:啰啰嗦嗦说了这么多,也不知道各位听懂了没有,本文并没有涉及到各种算法的具体实现过程(其实我也不会),只是想把各类算法简要介绍一下,消除菜鸟对密码学的恐惧感,如果你想了解更详细的内容,请参考各位大侠的文章,让我们共同提高吧.