加密与解密基础知识


第七章 加密与解密基础知识 7.1 加密技术的原理 加密可提高终端和网络通讯的物理安全,有三种方法加密传输数据: 链接加密:在网络节点间加密,在节点间传输加密,传送到节点后解密,不同节点对间 用不同的密码。 节点加密:与链接加密类似,不同的只是当数据在节点间传送时,不用明 码格式传送, 而是用特殊的加密硬件进行解密和重加密,这种专用硬件通常旋转在安全保险箱中。 首尾加密:对进入网络的数据加密,然后待数据从网络传送出后再进行解密。网络本身 并不会知道正在传送的数据是加密数据。这一方法的优点是,网络上的每个用户(通常是每 个机器的一个用户)可有不同的加密关键词,并且网络本身不需增添任何专门的加密设备。 缺点是每个系统必须有一个加密设备和相应的软件(管理加密关键词) 或者每个系统必须 自己完成加密工作(当数据传输率是按兆位/秒的单位计算时,加密任务的计算量是很大的) 终端数据加密是一特殊情况,此时链接加密法和首尾加密法是一样的方法,终端和计算 机都是既为节点又为终止端点。 通讯数据加密常常不同于文件加密,加密所用的方法不应降低数据的传送速度。丢失或 被歪曲了的数据不应当引起丢失更多的数据位,即解密进程应当能修复坏数据,而不能由于 坏数据对整个文件或登录进行不正确地解密。对于 登录会话,必须一次加密一个字节,特 别是在 UNIX 系统的情况下,系统要将字所返回给用户,更应一次加密一个字节。在网络中, 每一链可能需要不同的加密关键字,这就提出了对加密关键词的管理,分配和替换问题。 DES 传送数据的一般形式是以代入法密码格式按块传送数据,不能达到上述的许多要 求。DES 采用另一加密方法,一次加密一位或一个字节,形成密码流。密码流具有自同步 的特点,被传送的密码文本中发生的错误和数据丢失,将只影响最终的明码文本的一小段(64 位)。这称为密码反馈。在这种方法中,DES 被用作虚拟随机数发生器,产生出一系列用于 对明码文本的随机数。明码文本的 每 n 位与一个 DESn 位的加密输出数进行异或,n 的取 值为 1-64,DES 加密处理的输入是根据前边传送的密码文本形成的 64 位的数值。 发 n 为 1 时,加密方法是自同步方式:错一位或丢失 1 位后,64 位的密码文本将不能 被正确地解密,因为不正确的加密值将移入 DES 输入的末端。但是一旦接收到正确的 64 位 密码,由于 DES 的加密和解密的输入是同步的,故解密将继续正确地进行。 DES 的初始输入称为种子,是一个同时由传输器和接收器认可的随机数。通常种子由 一方选择,在加密前给另一方。而加密关键词不能以明码格式通过网 络传送,当加密系统 加电时在两边都写入加密关键词,并且在许多阶段期间加密关键词都保持不变,用户可以选 择由主关键词加密的阶段关键词,发送到数据传送的另一端,当该阶段结束后,阶段关键词 就不再使用了。主关键词对用户是不可见的,由系统管理员定期改变,选择哪一种关键词管 理方法,常由所用的硬件来确定。如果加密硬件都有相应的设备,则用种子还是用主关键词 阶段关键词是无关紧要的。 (3)用户身份鉴别 口令只是识别一个用户的一种方法,实际上有许多方法可以用来识别用户。 CALL BACK MODEM:则维护系统有效用户表及其相应电话号码的设备。当用户拨号 调用系统时,CALL BACK MODEM 获得用户的登录户头,挂起,再回头调用用户的终端。 这种方法的优点是,限制只有电话号码存于 MODEM 中的人才是系统的用户,从而使非法 侵入者不能从其 家里调用系统并登录,这一方法的缺点是限制了用户的灵活性,并仍需要 使用口令,因为 MODEM 不能仅从用户发出调用的地方,唯一地标识用户。标记识别:标 记是口令的物理实现,许多标记识别系统使用某种形式的卡(如背面有磁条的信用卡),这 种卡含有一个编码后的随机数。卡由连接到终端的阅卡机读入,不用再敲入口令。为了增加 安全性,有的系统要求读入卡和敲入口令。有些卡的编码方法使得编码难 于复制。标记识 别的优点是,标识可以是随机的并且必须长于口令。不足之处是每个用户必须携带一个卡(卡 也可与公司的徽记组合使用)。并且每个终端上必须连接一个阅读机。 一次性口令:即“询问-应答系统”。一次性口令系统允许用户每次登录时 使用不同的 口令。这种系统允许用户每次登录时使用不同的口令。这种系统使用一种称做口令发生器的 设备,设备是手携式的(大约为一个袖珍计算器的大小),并有一个加密程序和独一的内部 加密关键词。系统在用户登录时给用户提供一个随机数,用户将这个随 机数送入口令发生 器,口令发生器用用户的关键词对随机数加密,然后用户再将口令发生器输出的加密口令(回 答)送入系统,系统 将用户输入的口令,与它用相同的加密程序,关键词和随机数产生 的 口令比较,如果二者相同,允许用户存取系统。这种方法的优点是:用户可每次敲入不同的 口令,因此不需要口令保密,唯有口令发生器需要安全保护。为了增加安全性,UNIX 系统 甚至不需联机保存关键词,实际的关键词可保存在有线连接于系统的一个特殊加密计算机 中。在用户登录期间,加密计算机将为用户产生随机数和加密口令。这样一种系统的优点是, 口令实际不由用户输入,系统中也不保存关键词,即使是加密格式的关键词也可保存于系统 中。其不足之处类似于标记识别方法,每个用户必须携带口令发生器,如果要脱机保存关键 词,还需要有一个特殊硬件。 个人特征:有些识别系统检测如指印,签名,声音,零售图案这倦的物理特征。大多数 这样的系统极是实验性的,昂贵的,并且不是百分之 百的可靠。任何一个送数据到远程系 统去核实的系统有被搭线窃听的危险,非法入侵者只须记录下送去系统校核的信息,以后再 重 显示这些信息,就能窃密。注意:这同样也是标记识别系统的一个问题。 7.1.1 Windows 加密技术原理 绝大多数的网络管理员在考虑网络安全性时,都把重点放在如何防止从企业网络外部发 起的攻击,防火墙、安全路由器、拨号访问的令牌验证等概念也就出现了。这些措施无疑大 大增强了企业网络的周围防线,但所有这些都不能杜绝来自企业网内部的攻击。很多重要的 机密信息的泄露与遗失往往是由于企业雇员、技术支持人员或临时合同工从内部侵入公司网 络造成的。 针对上述情况,Windows 2000 推出了一种新的网络安全性方案——IP Security(IP 安 全性),它符合 IETF 宣布的 IP 安全性协议的标准,支持在网络层一级的验证、数据完整性 和加密。IP Security 与 Windows NT Server 内置的安全性集成在一起,为维护安全的 Inte rnet 和 intranet 通信,WindowsWINDOWS 2000 提供了一个理想的平台。微软的 Windows IP Security 使用基于工业标准的加密算法和全面的安全性管理方法,它为发生在企业防火墙两 侧的所有基于 TCP/IP 的通信提供了安全性,这种新的安全性战略使 Windows 2000 能够同时 抵御来自内部和外部的攻击。 由于 Windows IP Security 的实现是位于传输层之下(网络层),因此网络管理员和软件 开发商就不需要为每一个应用程序重新设置新的安全性,它的这些功能的实现是透明的。通 过 Windows 2000 的实施,网络管理员为网络提供了一层强有力的保护,而所有的应用程序 都自动地继承了 Windows NT 提供的新的安全性。 1.IP Security 的优势在于: (1)支持工业标准 与专用的 IP 加密技术不同,IP Security 提供的是一种基于公开工业标准的方法,网络 管理员从良好的互操作性中得到益处。Windows 2000 采用了以下符合工业标准的加密算法 和验证技术: Diffie-hellman 方法:Diffie-hellman 方法是一种公共密钥密码算法,它使得两个通信 主体协同商定一个共享密钥。首先两个主体互相交换公共信息,然后每个主体把另一个主体 的公共信息与自己的秘密信息结合在一起,产生一个共享秘密的密钥值。 HMAC(杂凑信息验证代码)算法:HMAC 是一种秘密密钥算法,它提供数据的完整 性和验证。首先,它对数据包使用带密钥的杂凑算法,产生一个接收方可以进行验证的数字 签名。如果信息在传输的过程中被改变,那么杂凑值必然与原来的数字签名有所不同,于是 接收方把这个 IP 数据包丢弃。HMAC 有不同的具体杂凑实现算法,它们产生不同长度的数 字签名,分别对应不同级别的安全性要求。 DES-CBC(数据加密标准-密码块链):DES-CBC 是一种秘密密钥算法,它使用一 个随机生成数结合秘密密钥对数据进行加密,它能为网络中传输的数据提供机密性。 (2)灵活的安全性协议 Windows 2000 使用不同的安全性协议来为网络通信提供不同级别的安全性服务,这些 安全协议利用的是上述各种工业标准的加密和验证算法。 ISAKMP(Internet 安全关联与密钥管理协议):SA(安全关联)定义的是安全通信机 制或服务必不可少的一组参数,比如密钥。在传送 IP 数据包之前,使用 IP Security 的两个 通信主体之间必须建立一个 SA,ISAKMP 为如何建立 SA 定义了一个通用的框架。 Oakley:Oakley 是一个密钥确定协议。它使用 Diffie-hellman 密钥交换算法来决定密 钥的生成。 IP AH(验证报头):IP AH 提供数据的完整性、验证并防止 IP 数据包的重复发送,但 是它不支持数据加密。IP AH 使用 HMAC 为每一个 IP 数据包计算出一个带密钥的消息杂凑 (数字签名)。 IP ESP(IP 封装安全协议):IP ESP 使用 DES-CBC 算法为数据传输进行加密,提供机 密性。 (3)灵活的协商策略 在实际应用中,由协商策略决定到底使用哪一种安全性协议,也就是提供哪一级别的安 全性,比如是否需要提供数据加密。管理员可以为每一个协商策略设置多个安全性协议,这 样在建立 SA 时,如果协商策略中的第一个安全性协议不能满足要求,ISAKMP/Oakley 可以 继续搜索协商策略中的其它安全性协议,找到一个符合要求的之后建立对应的 SA。 (4)灵活的安全性策略 对 Windows IP Security 属性的配置叫做安全性策略,安全性策略是建立在相关联的协商 策略和 IP 过滤器上的。IP 过滤器可以分析 IP 数据包使用的 IP 地址和协议,IP 过滤器使得 网络管理员能够根据 IP 地址和协议对不同的计算机采用不同的安全性策略。我们可以把安 全性策略加到缺省域策略或缺省本地策略中,这样,当域中的计算机自动地实现缺省域策略 和缺省本地策略时,它也自动地实现了其中的安全性策略。 (5)节省费用 通常情况下,为数据通信增加安全性的保证意味着高额的费用,因为软件的升级,用户 的培训以及密钥的管理都需要耗费大量的资金。有时对安全性的投资甚至可能超过对网络硬 件的投资。但 Windows IP Security 不但不需要增加现有的开支,还能够减少原有的管理费用。 首先,因为 IP Security 是在传输层以下实现的,因此它对应用程序层的具体的软件程序 是透明的。IP Security 为网络提供安全性,所有的应用程序都能够继承这种安全性,而不需 要做出任何的修改,这就节省了软件升级的费用。 其次,因为 Windows 2000 IP Security 对用户也是透明的,因此也省去了用户培训的费 用。 (6)透明性 IP Security 存在于传输层之下,因此它对应用程序和用户来说都是透明的。也就是说, 当在防火墙和路由器上实现 IP Security 时,用户桌面的网络应用程序不需要做出任何的修 改。 (7)动态的密钥重新生成 在数据的通信过程中能够动态地重新生成密钥,这就更好地保护了数据并因此使其免受 攻击。 2.Windows 2000 被设计成既能提供高级别的数据安全性,同时又易于实现和管理。为 了建立安全性,Windows IP Security 的实现一般必须经过以下四个步骤: (1)信息评估 首先,对通过网络和 Internet 传输的数据和信息要进行评估。所有这些信息都可能被截 取、查看或修改。系统管理员需要决定哪一类信息是需要保密的,哪种通信方案最容易受到 攻击。 (2)建立通信方案 每一个公司都有自己的信息流模型,系统管理员可以参考这些模型来建立不同的通信方 案。比如,远程的销售机构可能把销售数据、定单和其它的商业信息发送到公司本部。每一 个这种通信过程都可以有不同的 IP Security 策略。同样,管理员还可以决定所有与人力资源 部门发生的通信都应该保密。 (3)决定所需要的安全级别 可以根据传输信息的敏感程度、易受攻击的程度来决定不同级别的安全性。网络管理员 可以通过 Windows 2000 的安全性管理器来快速而方便地设置合适的安全性级别。 (4)用安全性管理器来建立安全性策略 Windows 2000 的安全性管理器可以用来设置安全性算法,并把它们指派到计算机组或 者单一的一台计算机上。 3.安全性策略的创建 让我们用一个例子来看一看如何根据实际情况生成安全性策略。假设在公司中有一个集 中的立法部门,我们需要控制它与其它部门通信时的数据安全性:在立法部门内部的通信必 须保证信息的完整性,但不需要加密;而立法部门和公司的其它部门之间的通信则既需要保 证信息的完整性,又必须保证机密性,也就是需要加密。这时 Windows IP Security 可以使用 IP 过滤器对从立法部门发出的 IP 数据包进行处理,根据不同的 IP 地址来实现不同的安全性 策略:如果通信的目的地位于立法部门以外,Windows IP Security 采用可以提供数据完整性 和加密的安全性策略;如果数据包只是发送到立法部门内部的另一台计算机上,则相应的安 全性策略只须提供数据完整性,不需要加密。具体的实现步骤如下: (1)生成一个叫“立法”的安全性策略,并把它加入到缺省域策略中。当公司中的每 台计算机登录到域中时,计算机的策略代理将从目录服务中得到“立法”安全性策略。 (2)生成两个协商策略,并把它们关联到“立法”安全策略中。第一个协商策略:NP1 , 设置一个能够提供机密性的安全性协议。这将被应用在当立法部门的用户与非立法部门的用 户进行通信之时,此时对传输数据的要求是经过加密、验证和未被修改的。从上文可知,我 们可以使用 IP ESP 安全性协议。第二个协商策略:NP2,设置一个仅提供验证和数据完整 性的安全性协议。这将被应用于立法部门内部互相进行通信之时,此时对传输数据的要求是 经过验证并未被修改的。从上文可知,我们可以使用 IP AH 安全性协议。 (3)生成两个 IP 过滤器,并把它们关联到对应的协商策略上。立法部门的用户位于子 网 1 57.55.0.0,掩码是 255.255.0.0,非立法部门的用户位于子网 147.20.0.0,掩码是 255.255. 0.0。第一个 IP 过滤器:IP F1 是立法部门的用户与非立法部门用户通信之时起作用,它将与 第一个协商策略 NP1 关联在一起。管理员设置以下过滤器值: 源地址(数据发送地址)为 157.55.0.0; 目的地地址(数据接收地址)为 147.20.0.0; 协议类型为任意(ANY),因为公司的安全性规划必须保证所有 IP 数据包的安全。 立法部门的用户与本部门的用户通信时,将使用第二个 IP 过滤器:IP F2。它将与第二 个协商协议 NP2 关联在一起,IP F2 的属性值应该设置如下: 源地址为 157.55.0.0。 目的地地址为 157.55.0.0。 协议类型为任意。 当一个立法部门的用户把信息发送到其它用户时,“立法”安全性策略中的 IP 过滤器将 对 IP 数据包的源地址和目的地地址进行检查,如果地址符合某个过滤器,则相应的协商策 略决定通信的安全性的级别。 基本实现图 例如,一个位于 Host A 上的用户 1 向 Host B 上的用户 2 发送数据,在两个计算机上都 启动了 IP Security。 从用户的角度来看,对 IP 数据包设置的安全性是透明的。用户 1 只是简单地启动了一 个使用 TCP/IP 的应用程序,比如 FTP,并向用户 2 发送数据。 网络管理员为 Host A 和 Host B 设置的安全性策略决定了通信的安全性级别。计算机的 策略代理得到安全性策略之后,把它传给 ISAKMP/Oakley 服务(协议)和 IPSEC 驱动程序。 每台计算机上的 ISAKMP/Oakley 服务使用关联到安全性策略上的协商策略来共同建立密 钥和 SA,然后把这些协商的结果传递给 IPSEC 驱动程序,再由驱动程序使用密钥对数据进 行加密。最后,由 IPSEC 驱动程序把加密后的数据发送到 Host B 上,Host B 上的 IPSEC 驱 动程序对数据进行解密,并把解密后的数据传递给接收方的应用程序。 7.1.2 软件加密的方法及原理 加密,在计算机领域中早已不是一个陌生的词汇。由于目前我国的软件保护法制还不太 健全,人们的法制观念也比较淡薄,并且计算机软件是一种特殊的商品,极易复制,所以加 密就成为了保护软件的一种必要手段。现在市场上流行的软件多数都采取了一定的加密方 法,其目的就在于保护软件开发者的利益,防止软件被盗版。本文将对目前常用的加密方法 与本人现发明的新软盘加密法进行分析和比较,以供软件开发商们参考。 有时尽管软件商做了加密工作,但由于选择的加密产品性能及方法不太好,可靠性不够 高;于是被一些不法分子解密并以特低价投入市场,严重危害了软件开发者的合法权益。目 前的解密方法主要可分外两种:软解密和硬解密 所谓软解密就是针对加密产品,一方面是利用软件监测分析软件在运行时向加密点写了 什么数据,从加密点返回了什么数据,然后在运行软件前先在内存驻留自编程序监视加密点, 当软件向加密点写数据时,软件自动代替加密点并返回相应数据。这样,用软件模拟了加密 产品。另一方面是从软件着手,寻找软件调用加密点函数部分,修改判断加密点是否存在的 语句,将程序直接跳转到正常执行的部分。如:打狗棒 Dog、Unlock95、解密之星 Llgz35、 Magickey、Msc、密界克星 Sc40、Soft-ICE、Ulm、Unall 等。但这种解密并不一定很彻底, 由于加密者的设计,这种解密后的软件往往设有一定的陷阱,如闹的沸沸扬扬的 KV300 逻 辑锁事件;再者软件商在短时间内即做一次软件升级,使解密者难于应付。因而除一些出于 学习目的的人购买盗版软件外,一般各种单位公司等软件的正式用户还是比较注重软件的可 靠性,购买正版软件的。因而可以说软解密对于软件开发商的利益损害并不算大。 所谓硬解密就是针对加密产品,专门研究加密点结构与数据,而自制具有相同结构及加 密点的钥匙盘或加密狗。如目前流行的一种由成都双星软件技术工作室推出的密钥盘硬解密 工具 KING_COPY,令广大解密爱好者欣喜若狂,更使软件开发商恨之入骨。这样的硬解密 软件除了不是原软件开发商出售的,利益完全被盗版者获得外,其余皆与正版一样,甚至享 有免费升级及售后服务的权利。如著名的杀毒软件 KV300,市面上不少公司卖的所谓正版, 实际上不是江民公司的产品。而是盗版者的硬解密产品。愿意购买正版软件的广大用户并不 能分清这是盗版。并且购买这种所谓的“正版”后,大多得不到免费升级等售后服务,因而给 广大用户带来不便。用户们因分辨不清是否是真正的正版,从而不愿再购买此软件,而改买 别的同类软件!因而这种硬解密对于软件开发商的利益损害极大。明智的软件开发商在选择 加密方法时,应把注意力集中到这种产品是否易被硬解密上。 目前正在采用的加密方法可分为两大类:钥匙盘方式和加密狗方式。加密狗,也是目前 流行的一种加密工具。它是插在计算机并行口上的软硬件结合的软件加密产品。加密狗一般 都有几十或几百字节的非易失性存储空间可供读写,有的内部还增添了一个单片机。软件运 行时通过向并口写入一定数据,判断从并口返回密码数据正确与否来检查加密狗是否存在。 此种方式不易被硬解密,因而具有加密可靠等优点。但它也存在一大缺点是成本较高,并且 用户使用很不方便。若用户购买了几种带加密狗的软件,在使用不同软件或更换微机时要不 断将狗换插,给用户增添了很多麻烦。 所谓钥匙盘方式就是通过 BIOS 的 INT13 中断对软盘格式化一些特殊的磁道,有的还在 特殊磁道里写入一定信息,软件在运行时要校验这些信息。这种软盘就好象一把钥匙一样, 所以被人习惯称为钥匙盘。它也是目前流行的一种加密工具。采用此种加密方式的软加密工 具有很多,如 Softlock、Bitlok、 Keymaker、Lock95、Lockstar 等。软件商只需一次性投资 购买一套加密工具,就可自己制作多张钥匙盘,在软件中读取钥匙盘上的特殊磁道来检查钥 匙盘是否存在。此种方式加密简便,成本低,用户使用方便。使用此种加密方式的软件也比 较多,如 KILL、KV300、瑞星杀毒软件等。此种方式存在一大缺陷是易被硬解密(因为别 人也可学会通过 BIOS 的 INT13 中断格式化技术),也就是易被非法者生成相同的钥匙盘而 作为正版出售。如 KV300 目前的窘况,江民公司采用这种加密技术保护不了自己的利益, 只好一再声明用户注意所谓正版激光防伪标志。 现在还有软盘加密方法,姑且叫它软盘锁,可以说是利用软盘加密的一场革命性突破! 本人通过对软磁盘驱动器的四大组成部分主轴驱动系统、定位系统、读写系统和整机控制系 统的深入研究,掌握了软盘控制器 FDC 在读写软盘信息时是怎样与主存储器交换信息的等 原理。绕过 BIOS 提供的 INT13 中断,采用特殊接口板硬件对软盘加密,所有微机皆可方便 读出密码点。 7.1.3 网络加密原理 随着计算机网络技术的飞速发展,大大改变了人们的生活面貌,促进了社会的发展。互 联网是一个面向大众的开放系统,对于信息的保密合系统的安全性考虑得并不完备,由此引 起得网络安全问题日益严重。如何保护计算机信息的的内容,也即信息内容的保密问题显得 越来越重要。 本质上讲,网络安全就是网络上的信息安全。从广义上来说,凡是涉及到网络信息的保 密性、完整性、可用性、真实性和可控性得相关技术和理论都是网络安全的研究领域。 信息安全的技术主要包括监控、扫描、检测、加密、认证、防攻击、防病毒以及审计等 几个方面,其中加密技术是信息安全的核心技术,已经渗透到大部分安全产品之中,并正向 芯片化方向发展。 在保障信息安全各种功能特性的诸多技术中,密码技术是信息安全的核心和关键技术, 通过数据加密技术,可以在一定程度上提高数据传输的安全性,保证传输数据的完整性。一 个数据加密系统包括加密算法、明文、密文以及密钥,密钥控制加密和解密过程,一个加密 系统的全部安全性是基于密钥的,而不是基于算法,所以加密系统的密钥管理是一个非常重 要的问题。 数据加密过程就是通过加密系统把原始的数字信息(明文),按照加密算法变换成与明 文完全不同得数字信息(密文)的过程。 假设E 为加密算法,D 为解密算法,则数据的加密解密数学表达式为:P=D(KD,E (KE,P)) 常用的数据加密技术有: 数据加密技术主要分为数据传输加密和数据存储加密。数据传输加密技术主要是对传输 中的数据流进行加密,常用的有链路加密、节点加密和端到端加密三种方式。 链路加密是传输数据仅在物理层前的数据链路层进行加密,不考虑信源和信宿,它用于 保护通信节点间的数据,接收方是传送路径上的各台节点机,信息在每台节点机内都要被解 密和再加密,依次进行,直至到达目的地。 与链路加密类似的节点加密方法,是在节点处采用一个与节点机相连的密码装置,密文 在该装置中被解密并被重新加密,明文不通过节点机,避免了链路加密节点处易受攻击的缺 点。 端到端加密是为数据从一端到另一端提供的加密方式。数据在发送端被加密,在接收端 解密,中间节点处不以明文的形式出现。端到端加密是在应用层完成的。在端到端加密中, 除报头外的的报文均以密文的形式贯穿于全部传输过程,只是在发送端和接收端才有加、解 密设备,而在中间任何节点报文均不解密,因此,不需要有密码设备,同链路加密相比,可 减少密码设备的数量。另一方面,信息是由报头和报文组成的,报文为要传送的信息,报头 为路由选择信息,由于网络传输中要涉及到路由选择,在链路加密时,报文和报头两者均须 加密。而在端到端加密时,由于通道上的每一个中间节点虽不对报文解密,但为将报文传送 到目的地,必须检查路由选择信息,因此,只能加密报文,而不能对报头加密。这样就容易 被某些通信分析发觉,而从中获取某些敏感信息。 链路加密对用户来说比较容易,使用的密钥较少,而端到端加密比较灵活,对用户可见。 在对链路加密中各节点安全状况不放心的情况下也可使用端到端加密方式。 常用数据加密算法有: 数据加密算法有很多种,密码算法标准化是信息化社会发展得必然趋势,是世界各国保 密通信领域得一个重要课题。按照发展进程来分,经历了古典密码、对称密钥密码和公开密 钥密码阶段,古典密码算法有替代加密、置换加密;对称加密算法包括 DES 和 AES;非对 称加密算法包括 RSA 、背包密码、McEliece 密码、Rabin、椭圆曲线、EIGamal D_H 等。 目前在数据通信中使用最普遍的算法有 DES 算法、RSA 算法和 PGP 算法等。 密码技术是信息安全的核心技术,无处不在,目前已经渗透到大部分安全产品之中,正 向芯片化方向发展。在芯片设计制造方面,目前微电子水平已经发展到 0。1 微米工艺以下, 芯片设计的水平很高。 现在量子技术也在密码学上的应用,可以分为两类:一是利用量子计算机对传统密码体 制的分析;二是利用单光子的测不准原理在光纤一级实现密钥管理和信息加密,即量子密码 学。量子计算机是一种传统意义上的超大规模并行计算系统,利用量子计算机可以在几秒钟 内分解 RSA129 的公钥。根据 internet 的发展,全光网络将是今后网络连接的发展方向,利 用量子技术可以实现传统的密码体制,在光纤一级完成密钥交换和信息加密,其安全性是建 立在 Heisenberg 的测不准原理上的,如果攻击者企图接收并检测信息发送方的信息(偏振), 则将造成量子状态的改变,这种改变对攻击者而言是不可恢复的,而对收发方则可很容易地 检测出信息是否受到攻击。目前量子加密技术仍然处于研究阶段,其量子密钥分配 QKD 在 光纤上的有效距离还达不到远距离光纤通信的要求。 7.1.4信息加密概述 随着计算机联网的逐步实现,计算机信息的保密问题显得越来越重要。数据保密变换, 或密码技术,是对计算机信息进行保护的最实用和最可靠的方法,本节对信息加密技术作一 简要介绍。 一、信息加密概述 密码学是一门古老而深奥的学科,它对一般人来说是莫生的,因为长期以来,它只在很 少的范围内,如军事、外交、情报等部门使用。计算机密码学是研究计算机信息加密、解密 及其变换的科学,是数学和计算机的交义学科,也是一门新兴的学科。随着计算机网络和计 算机通讯技术的发展,计算机密码学得到前所未有的重视并迅速普及和发展起来。在国外, 它已成为计算机安全主要的研究方向,也是计算机安全课程教学中的主要内容。 密码是实现秘密通讯的主要手段,是隐蔽语言、文字、图象的特种符号。凡是用特种符 号按照通讯双方约定的方法把电文的原形隐蔽起来,不为第三者所识别的通讯方式称为密码 通讯。在计算机通讯中,采用密码技术将信息隐蔽起来,再将隐蔽后的信息传输出去,使信 息在传输过程中即使被窃取或载获,窃取者也不能了解信息的内容,从而保证信息传输的安 全。任何一个加密系统至少包括下面四个组成部分: (1)未加密的报文,也称明文。 (2)加密后的报文,也称密文。 (3)加密解密设备或算法。 (4)加密解密的密钥。 发送方用加密密钥,通过加密设备或算法,将信息加密后发送出去。接收方在收到密文 后,用解密密钥将密文解密,恢复为明文。如果传输中有人窃取,他只能得到无法理解的密 文,从而对信息起到保密作用。 二、密码的分类 从不同的角度根据不同的标准,可以把密码分成若干类。 (一)按应用技术或历史发展阶段划分: 1.手工密码。以手工完成加密作业,或者以简单器具辅助操作的密码,叫作手工密码。 第一次世界大战前主要是这种作业形式。 2.机械密码。以机械密码机或电动密码机来完成加解密作业的密码,叫作机械密码。 这种密码从第一次世界大战出现到第二次世界大战中得到普遍应用。 3.电子机内乱密码。通过电子电路,以严格的程序进行逻辑运算,以少量制乱元素生 产大量的加密乱数,因为其制乱是在加解密过程中完成的而不需预先制作,所以称为电子机 内乱密码。从五十年代末期出现到七十年代广泛应用。 4.计算机密码,是以计算机软件编程进行算法加密为特点,适用于计算机数据保护和 网络通讯等广泛用途的密码。 (二)按保密程度划分: 1.理论上保密的密码。不管获取多少密文和有多大的计算能力,对明文始终不能得到 唯一解的密码,叫作理论上保密的密码。也叫理论不可破的密码。如客观随机一次一密的密 码就属于这种。 2.实际上保密的密码。在理论上可破,但在现有客观条件下,无法通过计算来确定唯 一解的密码,叫作实际上保密的密码。 3.不保密的密码。在获取一定数量的密文后可以得到唯一解的密码,叫作不保密密码。 如早期单表代替密码,后来的多表代替密码,以及明文加少量密钥等密码,现在都成为不保 密的密码。 (三)按密钥方式划分: 1.对称式密码。收发双方使用相同密钥的密码,叫作对称式密码。传统的密码都属此 类。 2.非对称式密码。收发双方使用不同密钥的密码,叫作非对称式密码。如现代密码中 的公共密钥密码就属此类。 (四)按明文形态: 1.模拟型密码。用以加密模拟信息。如对动态范围之内,连续变化的语音信号加密的 密码,叫作模拟式密码。 2.数字型密码。用于加密数字信息。对两个离散电平构成 0、1 二进制关系的电报信息 加密的密码叫作数字型密码。 (五)按编制原理划分: 可分为移位、代替和置换三种以及它们的组合形式。古今中外的密码,不论其形态多么 繁杂,变化多么巧妙,都是按照这三种基本原理编制出来的。移位、代替和置换这三种原理 在密码编制和使用中相互结合,灵活应用。 三、近代加密技术 (一)数据加密标准 数据加密标准(DES)是美国经长时间征集和筛选后,于 1977 年由美国国家标准局颁 布的一种加密算法。它主要用于民用敏感信息的加密,后来被国际标准化组织接受作为国际 标准。DES 主要采用替换和移位的方法加密。它用 56 位密钥对 64 位二进制数据块进行加 密,每次加密可对 64 位的输入数据进行 16 轮编码,经一系列替换和移位后,输入的 64 位 原始数据转换成完全不同的 64 位输出数据。DES 算法仅使用最大为 64 位的标准算术和逻 辑运算,运算速度快,密钥生产容易,适合于在当前大多数计算机上用软件方法实现,同时 也适合于在专用芯片上实现。 DES 主要的应用范围有: (1)计算机网络通信:对计算机网络通信中的数据提供保护是 DES 的一项重要应用。 但这些被保护的数据一般只限于民用敏感信息,即不在政府确定的保密范围之内的信息。 (2)电子资金传送系统:采用 DES 的方法加密电子资金传送系统中的信息,可准确、 快速地传送数据,并可较好地解决信息安全的问题。 (3)保护用户文件:用户可自选密钥对重要文件加密,防止未授权用户窃密。 (4)用户识别:DES 还可用于计算机用户识别系统中。 DES 是一种世界公认的较好的加密算法。自它问世 20 多年来,成为密码界研究的重点, 经受住了许多科学家的研究和破译,在民用密码领域得到了广泛的应用。它曾为全球贸易、 金融等非官方部门提供了可靠的通信安全保障。但是任何加密算法都不可能是十全十美的。 它的缺点是密钥太短(56 位),影响了它的保密强度。此外,由于 DES 算法完全公开,其 安全性完全依赖于对密钥的保护,必须有可靠的信道来分发密钥。如采用信使递送密钥等。 因此,它不适合在网络环境下单独使用。 针对它密钥短的问题,科学家又研制了 80 位的密钥,以及在 DES 的基础上采用三重 DES 和双密钥加密的方法。即用两个 56 位的密钥 K1、K2,发送方用 K1 加密,K2 解密, 再使用 K1 加密。接收方则使用 K1 解密,K2 加密,再使用 K1 解密,其效果相当于将密钥 长度加倍。 (二)国际数据加密算法 国际数据加密算法 IDEA 是瑞士的著名学者提出的。它在 1990 年正式公布并在以后得 到增强。这种算法是在 DES 算法的基础上发展出来的,类似于三重 DES。发展 IDEA 也是 因为感到 DES 具有密钥太短等缺点,已经过时。IDEA 的密钥为 128 位,这么长的密钥在今 后若干年内应该是安全的。 类似于 DES,IDEA 算法也是一种数据块加密算法,它设计了一系列加密轮次,每轮加 密都使用从完整的加密密钥中生成的一个子密钥。与 DES 的不同处在于,它采用软件实现 和采用硬件实现同样快速。 由于 IDEA 是在美国之外提出并发展起来的,避开了美国法律上对加密技术的诸多限 制,因此,有关 IDEA 算法和实现技术的书籍都可以自由出版和交流,可极大地促进 IDEA 的发展和完善。但由于该算法出现的时间不长,针对它的攻击也还不多,还未经过较长时间 的考验。因此,尚不能判断出它的优势和缺陷。 (三)clipper 加密芯片 密码虽然可为私人提供信息保密服务,但是它首先是维护国家利益的工具。正是基于这 个出发点,考虑到 DES 算法公开后带来的种种问题,美国国家保密局(NSA)从 1985 年起 开始着手制定新的商用数据加密标准,以取代 DES。1990 年开始试用,1993 年正式使用, 主要用于通信交换系统中电话、传真和计算机通信信息的安全保护。 新的数据加密标准完全改变了过去的政策,密码算法不再公开,对用户提供加密芯片 (clipper)和硬件设备。新算法的安全性远高于 DES,其密钥量比 DES 多 1000 多万倍。据 估算,穷举破译至少需要 10 亿年。为确保安全,clipper 芯片由一个公司制造裸片,再由另 一公司编程后方可使用。 由于完全是官方的封闭控制,该算法除可提供高强度的密码报密外,还可对保密通信进 行监听,以防止不法分子利用保密通信进行非法活动,但这种监听是在法律允许的范围内进 行的。官方控制也成为美国民间反对该方案的一个重要原因。 Clipper 芯片主要用于商业活动的计算机通信网。NSA 同时在着手进行政府和军事通信 网中数据加密芯片的研究,并作为 clipper 的换代产品。它除了具有 clipper 的全部功能外, 还将实现美国数字签名标准(DSS)和保密的哈稀函数标准以及用纯噪声源产生随机数据的 算法等 (四)公开密钥密码体制 传统的加密方法是加密、解密使用同样的密钥,由发送者和接收者分别保存,在加密和 解密时使用,采用这种方法的主要问题是密钥的生成、注入、存储、管理、分发等很复杂, 特别是随着用户的增加,密钥的需求量成倍增加。在网络通信中,大量密钥的分配是一个难 以解决的问题。 例如,若系统中有 n 个用户,其中每两个用户之间需要建立密码通信,则系统中每个用 户须掌握(n-1)/2 个密钥,而系统中所需的密钥总数为 n*(n-1)/2 个。对 10 个用户的情 况,每个用户必须有 9 个密钥,系统中密钥的总数为 45 个。对 100 个用户来说,每个用户 必须有 99 个密钥,系统中密钥的总数为 4950 个。这还仅考虑用户之间的通信只使用一种会 话密钥的情况。如此庞大数量的密钥生成、管理、分发确实是一个难处理的问题。 本世纪 70 年代,美国斯坦福大学的两名学者迪菲和赫尔曼提出了一种新的加密方法-- 公开密钥加密队 PKE 方法。与传统的加密方法不同,该技术采用两个不同的密钥来对信息 加密和解密,它也称为"非对称式加密方法。每个用户有一个对外公开的加密算法 E 和对外 保密的解密算法 D,它们须满足条件: (1)D 是 E 的逆,即 D[E(X)]=X; (2)E 和 D 都容易计算。 (3)由 E 出发去求解 D 十分困难。 从上述条件可看出,公开密钥密码体制下,加密密钥不等于解密密钥。加密密钥可对外 公开,使任何用户都可将传送给此用户的信息用公开密钥加密发送,而该用户唯一保存的私 人密钥是保密的,也只有它能将密文复原、解密。虽然解密密钥理论上可由加密密钥推算出 来,但这种算法设计在实际上是不可能的,或者虽然能够推算出,但要花费很长的时间而成 为不可行的。所以将加密密钥公开也不会危害密钥的安全。 数学上的单向陷门函数的特点是一个方向求值很容易,但其逆向计算却很困难。许多形 式为 Y=f(x)的函数,对于给定的自变量 x 值,很容易计算出函数 Y 的值;而由给定的 Y 值,在很多情况下依照函数关系 f(x)计算 x 值十分困难。例如,两个大素数 p 和 q 相乘 得到乘积 n 比较容易计算,但从它们的乘积 n 分解为两个大素数 p 和 q 则十分困难。如果 n 为足够大,当前的算法不可能在有效的时间内实现。 正是基于这种理论,1978 年出现了著名的 RSA 算法。这种算法为公用网络上信息的加 密和鉴别提供了一种基本的方法。它通常是先生成一对 RSA 密钥,其中之一是保密密钥, 由用户保存;另一个为公开密钥,可对外公开,甚至可在网络服务器中注册。为提高保密强 度,RSA 密钥至少为 500 位长,一般推荐使用 1024 位。这就使加密的计算量很大。为减少 计算量,在传送信息时,常采用传统加密方法与公开密钥加密方法相结合的方式,即信息采 用改进的 DES 或 IDEA 对话密钥加密,然后使用 RSA 密钥加密对话密钥和信息摘要。对方 收到信息后,用不同的密钥解密并可核对信息摘要。 RSA 算法的加密密钥和加密算法分开,使得密钥分配更为方便。它特别符合计算机网 络环境。对于网上的大量用户,可以将加密密钥用电话簿的方式印出。如果某用户想与另一 用户进行保密通信,只需从公钥簿上查出对方的加密密钥,用它对所传送的信息加密发出即 可。对方收到信息后,用仅为自己所知的解密密钥将信息脱密,了解报文的内容。由此可看 出,RSA 算法解决了大量网络用户密钥管理的难题。 RSA 并不能替代 DES,它们的优缺点正好互补。 RSA 的密钥很长,加密速度慢,而采 用 DES,正好弥补了 RSA 的缺点。即 DES 用于明文加密,RSA 用于 DES 密钥的加密。由 于 DES 加密速度快,适合加密较长的报文;而 RSA 可解决 DES 密钥分配的问题。美国的 保密增强邮件(PEM)就是采用了 RSA 和 DES 结合的方法,目前已成为 E-MAIL 保密通 信标准。 四、局域网通信安全措施 对于局域网通信,可采用以下两种具体措施进行加密传输。这些措施的加、解密功能都 可以采用上述算法实现: (1)链路加密 链路加密是传输数据仅在物理层前的数据链路层进行加密。接收方是传送路径上的各台 节点机,信息在每台节点机内都要被解密和再加密,依次进行,直至到达目的地。 使用链路加密装置能为某链路上的所有报文提供传输服务。即经过一台节点机的所有网 络信息传输均需加、解密,每一个经过的节点都必须有密码装置,以便解密、加密报文。如 果报文仅在一部分链路上加密而在另一部分链路上不加密,则相当于未加密,仍然是不安全 的。与链路加密类似的节点加密方法,是在节点处采用一个与节点机相连的密码装置(被保 护的外围设备),密文在该装置中被解密并被重新加密,明文不通过节点机,避免了链路加 密关节点处易受攻击的缺点。 (2)端--端加密 端--端加密是为数据从一端传送到另一端提供的加密方式。数据在发送端被加密,在最 终目的地(接收端)解密,中间节点处不以明文的形式出现。 采用端--端加密是在应用层完成,即传输前的高层中完成。除报头外的的报文均以密文 的形式贯穿于全部传输过程。只是在发送端和最终端才有加、解密设备,而在中间任何节点 报文均不解密,因此,不需要有密码设备。同链路加密相比,可减少密码设备的数量。另一 方面,信息是由报头和报文组成的,报文为要传送的信息,报头为路由选择信息。由于网络 传输中要涉及到路由选择,在链路加密时,报文和报头两者均须加密。而在端--端加密时, 由于通道上的每一个中间节点虽不对报文解密,但为将报文传送到目的地,必须检查路由选 择信息,因此,只能加密报文,而不能对报头加密。这样就容易被某些通信分析发觉,而从 中获取某些敏感信息。 (3)加密传输方式的比较 数据保密变换使数据通信更安全,但不能保证在传输过程中绝对不会泄密。因为在传输 过程中,还有泄密的隐患。 采用链路加密方式,从起点到终点,要经过许多中间节点,在每个节点地均要暴露明文 (节点加密方法除外),如果链路上的某一节点安全防护比较薄弱,那么按照木桶原理(木 桶水量是由最低一块木板决定),虽然采取了加密措施,但整个链路的安全只相当于最薄弱 的节点处的安全状况。 采用端--端加密方式,只是发送方加密报文,接收方解密报文,中间节点不必加、解密, 也就不需要密码装置。此外,加密可采用软件实现,使用起来很方便。在端--端加密方式下, 每对用户之间都存在一条虚拟的保密信道,每对用户应共享密钥(传统密码保密体制,非公 钥体制下),所需的密钥总数等于用户对的数目。对于几个用户,若两两通信,共需密钥 n* (n-1)/2 种,每个用户需(n-1)种。这个数目将随网上通信用户的增加而增加。为安全起 见,每隔一段时间还要更换密钥,有时甚至只能使用一次密钥,密钥的用量很大。 链路加密,每条物理链路上,不管用户多少,可使用一种密钥。在极限情况下,每个节 点都与另外一个单独的节点相连,密钥的数目也只是 n*(n-1)/2 种。这里 n 是节点数而非 用户数,一个节点一般有多个用户。 从身份认证的角度看,链路加密只能认证节点,而不是用户。使用节点 A 密钥的报文 仅保证它来自节点 A。报文可能来自 A 的任何用户,也可能来自另一个路过节点 A 的用户。 因此链路加密不能提供用户鉴别。端--端加密对用户是可见的,可以看到加密后的结果,起 点、终点很明确,可以进行用户认证。 总之,链路加密对用户来说比较容易,使用的密钥较少,而端--端加密比较灵活,用户 可见。对链路加密中各节点安全状况不放心的用户也可使用端--端加密方式。 7.2 加密算法 密码系统的两个基本要素是加密算法和密钥管理。加密算法是一些公式和法则,它规定 了明文和密文之间的变换方法。由于密码系统的反复使用,仅靠加密算法已难以保证信息的 安全了。事实上,加密信息的安全可靠依赖于密钥系统,密钥是控制加密算法和解密算法的 关键信息,它的产生、传输、存储等工作是十分重要的。 在信息处理系统中,密码学的主要应用有两类:数据的通信保护和数据的存储保护。在 这些应用领域,密码方法的使用与过去在军事、外交上的传统使用方法有很大的区别。在传 统应用中,双方所需的密钥通过另外的安全途径传送;而在信息处理系统中,密钥的某些信 息必须放在机器中。如此一来,总有一些特权用户有机会存取密钥,这对加密系统的安全是 十分不利的。解决这一问题的方法之一是研制多级密钥管理体制。例如,在二级密钥管理体 制中,一级密钥(也称主密钥)存储在安全区域,用它对二级密钥信息加密生成二级密钥(也 称为工作密钥),再用工作密钥对数据加密。当然,这些动作都应该是连贯的密箱操作。然 而纯软件的加密系统难以做到密箱操作。 实际上,无论多么高明的反跟踪技术也难以让人放心,因为软件跟踪高手会将整个程序 分解、剖析。但如果把主密钥、加密算法等关键数据、程序固化在加密卡中,就能解决密箱 操作的难题。主程序将待加密的一组明文数据、一组二级密钥信息传给加密卡,加密卡则完 成以下的工作:用主密钥和加密算法将取得的一组二级密钥信息加密成工作密钥,再用该工 作密钥和加密算法将明文数据加密并将所得密文经接口返回给主程序。 数据库密码——应用于数据库加密的加密算法称为数据库密码。目前常用的加密算法可 分为三类: 1. 序列密码体制 这种密码直接对当前的字符进行变换,也就是说,以一个字符为单位进行加密变换。在 这种加密体制中,每一字符数据的加密与报文的其他部分无关。例如,直接对明文加上一串 同等长度的乱码(也可看成是密钥),只要所用的乱码是随机数且不重复使用,就实现了“一 次一密”的加密。从理论上讲,真正实现了“一次一密”的密码是可靠的密码,原则上是不 可破译的。这类密码的明文和密文长度一般不变,传递迅速、快捷;其缺点是密码破译人员 比较容易得到明密对照双码,便于其进行密码分析,同时乱码的产生和管理比较困难,难以 真正做到“一次一密”。该类密码适用于通信领域。 2. 分组密码体制 应用这类密码时,明文按固定长度分组,对各组数据用不同的密钥加密(或脱密)。这 类密码按分组进行加密变换,一个字符数据不仅与密钥有关,而且还与其他字符数据有关, 密码分析的穷尽量很大。例如传统的 64 位分组法,它的穷尽量为 264-1,这是一个 20 位 的十进制数,即使用每秒运算万亿次以上的巨型计算机进行攻击,平均穷尽时间也需要数年。 当然这仅仅是理论数据,在攻击密码时还有其他约束条件,如文字、数据、环境、规律等信 息,所以实际所需的攻击时间要短得多。 在使用分组密码时,对明文尾部不满一个整组的碎片通常采用填充随机数的办法将其扩 充为一个整组,然后进行正常加密。由于尾组的扩充,使得密文的长度大于明文的长度。分 组密码可用于计算机存储加密,但因为数据库加密后的数据长度不能改变,所以必须改进分 组加密算法的使用方法。 3. 公开密钥体制 -这种体制的一个例子是 RSA 密码。这类密码的共同缺点是加/脱密速度较慢,据报道, 这类密码的运算速率仅达到其他密码的千分之一到百分之一。公开密钥体制的密码目前常用 于用户认证、数字签名以及密钥传输等,不能适应数据库加密的速度要求。 序列密码和分组密码也称为对称性密码,这类密码加密时用某个密钥加密,脱密时还用 这个密钥脱密。公开密钥密码也称非对称密码,这类体制的密码具有两个密钥:公钥和私钥, 加密时用公钥加密,脱密时必须用私钥脱密。 数据库加密系统对数据库密码的要求如下: 数据库加密以后,数据量不应明显增加; 某一数据加密后,其数据长度不变; 加/脱 密速度要足够快,数据操作响应时间应该让用户能够接受。改变对分组密码算法传统的应用 处理方法,使其加密后密文长度不变,就能满足以上几点要求。 理论上讲,实现了“一次一密”密钥管理的密码是不可破译的,因此如何确保密钥管理 系统的安全成为关键问题。本系统中,主密钥保护了工作密钥,工作密钥保护敏感信息,因 而整个系统的安全依赖于主密钥的安全。 主密钥的安全需要解决以下几个问题: 1. 主密钥的生成 本系统采用投币法产生 64 位二进制数据。 2. 主密钥的存储 主密钥经加密并存放于安全区域内,使用时由系统自动获取并脱密。本系统也可将主密 钥注入加密卡中以利安全。 3. 主密钥的更换 在数据库加密课题中,主密钥的更换是一个比较棘手的问题。主密钥更换以后,会造成 工作密钥的全部更换。数据库中存储着海量数据,已经加密的数据需要用原来的密钥系统脱 密,而且脱密时间将会很长。为安全起见,密钥更换前,需对数据库系统进行全库备份,然 后利用系统所提供的工具完成对数据库中密数据向明数据的转换。更换主密钥后,再根据数 据库加密要求进行明数据向密数据的转换。 在大型数据库中,这种明密数据的转换工作需要认真对待。首先应该制定计划,做好充 分的准备工作。对所做的工作应做好登记,使密钥更换工作有条不紊地进行。事实上,由上 面密钥系统的应用分析可以知道,即使不变更主密钥,也可以在足够长的时间内保证 Xi 信 息的两两互异,也就是说,在通常的数据库生存期内,不变更主密钥也能充分保证加密系统 密钥使用的“一次一密”。只要系统管理得当,密钥系统仅需数年更换一次,或者不必更换。 7.1.1 DES算法 DES 算法全称为 Data Encryption Standard,即数据加密算法,它是 IBM 公司于 1975 年 研究成功并公开发表的。DES 算法的入口参数有三个:Key、Data、Mode。其中 Key 为 8 个字节共 64 位,是 DES 算法的工作密钥;Data 也为 8 个字节 64 位,是要被加密或被解密 的数据;Mode 为 DES 的工作方式,有两种:加密或解密。 DES 算法把 64 位的明文输入块变为 64 位的密文输出块,它所使用的密钥也是 64 位, 其算法主要分为两步: 1.初始置换 其功能是把输入的 64 位数据块按位重新组合,并把输出分为 L0、R0 两部分,每部分 各长 3 2 位,其置换规则为将输入的第 58 位换到第一位,第 50 位换到第 2 位等等依此类推, 最后一位是原来的第 7 位。L0、R0 则是换位输出后的两部分,L0 是输出的左 32 位,R0 是 右 32 位,例:设置换前的输入值为 D1D2D3……。D64,则经过初始置换后的结果为: L0=D58D50……D8;R0=D57D49……D7。 2.逆置换 经过16 次迭代运算后,得到 L16、R16,将此作为输入,进行逆置换,逆置换正好是初 始置换的逆运算,由此即得到密文输出。 我们下面来看看具体实现过程: 1-1 变换密钥 取得 64 位的密钥,每个第 8 位作为奇偶校验位。 1-2 变换密钥。 1-2-1 舍弃64 位密钥中的奇偶校验位,根据下表(PC-1)进行密钥变换得到 56 位的 密钥,在变换中,奇偶校验位以被舍弃。 Permuted Choice 1 (PC-1) 57 49 41 33 25 17 9 1 58 50 42 34 26 18 10 2 59 51 43 35 27 19 11 3 60 52 44 36 63 55 47 39 31 23 15 7 62 54 46 38 30 22 14 6 61 53 45 37 29 21 13 5 28 20 12 4 1-2-2 将变换后的密钥分为两个部分,开始的 28 位称为 C[0],最后的 28 位称为 D[0]。 1-2-3 生成16 个子密钥,初始 I=1。 1-2-3-1 同时将 C[I]、D[I]左移 1 位或 2 位,根据 I 值决定左移的位数。见下表 I: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 左移位数: 1 1 2 2 2 2 2 2 1 2 2 2 2 2 2 1 1-2-3-2 将C[I]D[I]作为一个整体按下表(PC-2)变换,得到 48 位的 K[I] Permuted Choice 2 (PC-2) 14 17 11 24 1 5 3 28 15 6 21 10 23 19 12 4 26 8 16 7 27 20 13 2 41 52 31 37 47 55 30 40 51 45 33 48 44 49 39 56 34 53 46 42 50 36 29 32 1-2-3-3 从1-2-3-1 处循环执行,直到 K[16]被计算完成。 2 处理64 位的数据 2-1 取得64 位的数据,如果数据长度不足 64 位,应该将其扩展为 64 位(例如补零) 2-2 将64 位数据按下表变换(IP) Initial Permutation (IP) 58 50 42 34 26 18 10 2 60 52 44 36 28 20 12 4 62 54 46 38 30 22 14 6 64 56 48 40 32 24 16 8 57 49 41 33 25 17 9 1 59 51 43 35 27 19 11 3 61 53 45 37 29 21 13 5 63 55 47 39 31 23 15 7 2-3 将变换后的数据分为两部分,开始的 32 位称为 L[0],最后的 32 位称为 R[0]。 2-4 用16 个子密钥加密数据,初始 I=1。 2-4-1 将32 位的 R[I-1]按下表(E)扩展为 48 位的 E[I-1] Expansion (E) 32 1 2 3 4 5 4 5 6 7 8 9 8 9 10 11 12 13 12 13 14 15 16 17 16 17 18 19 20 21 20 21 22 23 24 25 24 25 26 27 28 29 28 29 30 31 32 1 2-4-2 异或E[I-1]和 K[I],即 E[I-1] XOR K[I] 2-4-3 将异或后的结果分为 8 个 6 位长的部分,第 1 位到第 6 位称为 B[1],第 7 位到 第 12 位称为 B[2],依此类推,第 43 位到第 48 位称为 B[8]。 2-4-4 按S 表变换所有的 B[J],初始 J=1。所有在 S 表的值都被当作 4 位长度处理。 2-4-4-1 将B[J]的第 1 位和第 6 位组合为一个 2 位长度的变量 M,M 作为在 S[J]中的 行号。 2-4-4-2 将B[J]的第 2 位到第 5 位组合,作为一个 4 位长度的变量 N,N 作为在 S[J] 中的列号。 2-4-4-3 用S[J][M][N]来取代 B[J]。 Substitution Box 1 (S[1]) 14 4 13 1 2 15 11 8 3 10 6 12 5 9 0 7 0 15 7 4 14 2 13 1 10 6 12 11 9 5 3 8 4 1 14 8 13 6 2 11 15 12 9 7 3 10 5 0 15 12 8 2 4 9 1 7 5 11 3 14 10 0 6 13 S[2] 15 1 8 14 6 11 3 4 9 7 2 13 12 0 5 10 3 13 4 7 15 2 8 14 12 0 1 10 6 9 11 5 0 14 7 11 10 4 13 1 5 8 12 6 9 3 2 15 13 8 10 1 3 15 4 2 11 6 7 12 0 5 14 9 S[3] 10 0 9 14 6 3 15 5 1 13 12 7 11 4 2 8 13 7 0 9 3 4 6 10 2 8 5 14 12 11 15 1 13 6 4 9 8 15 3 0 11 1 2 12 5 10 14 7 1 10 13 0 6 9 8 7 4 15 14 3 11 5 2 12 S[4] 7 13 14 3 0 6 9 10 1 2 8 5 11 12 4 15 13 8 11 5 6 15 0 3 4 7 2 12 1 10 14 9 10 6 9 0 12 11 7 13 15 1 3 14 5 2 8 4 3 15 0 6 10 1 13 8 9 4 5 11 12 7 2 14 S[5] 2 12 4 1 7 10 11 6 8 5 3 15 13 0 14 9 14 11 2 12 4 7 13 1 5 0 15 10 3 9 8 6 4 2 1 11 10 13 7 8 15 9 12 5 6 3 0 14 11 8 12 7 1 14 2 13 6 15 0 9 10 4 5 3 S[6] 12 1 10 15 9 2 6 8 0 13 3 4 14 7 5 11 10 15 4 2 7 12 9 5 6 1 13 14 0 11 3 8 9 14 15 5 2 8 12 3 7 0 4 10 1 13 11 6 4 3 2 12 9 5 15 10 11 14 1 7 6 0 8 13 S[7] 4 11 2 14 15 0 8 13 3 12 9 7 5 10 6 1 13 0 11 7 4 9 1 10 14 3 5 12 2 15 8 6 1 4 11 13 12 3 7 14 10 15 6 8 0 5 9 2 6 11 13 8 1 4 10 7 9 5 0 15 14 2 3 12 S[8] 13 2 8 4 6 15 11 1 10 9 3 14 5 0 12 7 1 15 13 8 10 3 7 4 12 5 6 11 0 14 9 2 7 11 4 1 9 12 14 2 0 6 10 13 15 3 5 8 2 1 14 7 4 10 8 13 15 12 9 0 3 5 6 11 2-4-4-4 从2-4-4-1 处循环执行,直到 B[8]被替代完成。 2-4-4-5 将B[1]到 B[8]组合,按下表(P)变换,得到 P。 Permutation P 16 7 20 21 29 12 28 171 15 23 26 5 18 31 10 8 24 14 32 27 3 9 19 13 30 6 22 11 4 25 2-4-6 异或P 和 L[I-1]结果放在 R[I],即 R[I]=P XOR L[I-1]。 2-4-7 L[I]=R[I-1] 2-4-8 从2-4-1 处开始循环执行,直到 K[16]被变换完成。 2-4-5 组合变换后的 R[16]L[16](注意:R 作为开始的 32 位),按下表(IP-1)变换得 到最后的结果。 Final Permutation (IP**-1) 40 8 48 16 56 24 64 32 39 7 47 15 55 23 63 31 38 6 46 14 54 22 62 30 37 5 45 13 53 21 61 29 36 4 44 12 52 20 60 28 35 3 43 11 51 19 59 27 34 2 42 10 50 18 58 26 33 1 41 9 49 17 57 25 以上就是 DES 算法的描述。 7.1.2 RSA 算法 安全的问题有一个地方讲起来非常头大,就是网路窃听的问题因为现今大部分的资料传 递是使用明码,所以,有心人只要组一台 PC 上网,就可以窃听到许许多多有用的资讯,即 使机器的 su 密码也不能幸免所以,人们就想在资料上做加密解密的工作。在网路上所传输 的都是经过加密之後资料,来防止第三者窃听。 其实,对资料作加密解密的工作并不困难,只要会写程式的人就可以想出许许多多千奇 百怪的方法。但问题是,如果这个演算法一旦外流了,那这个方法就破功了。所传的码顿时 之间成为明码。所以,在一般公用的 service,如 telnet,ftp 等,作者不可能使用自定的演算 法作加密解密的工作。 现今,大家最常用的方法是 DES 演算法 DES 是一个公开的演算法,但它在加密解密的 过程中需要一个 key。解码时如果 key 不对,那还是没效。所以,只要 key 不要外流,即使 传输过程中有人窃听,也不怕资料曝光。但 DES 有个问题,因为加密解密需用同一个 key, 所以在传输时,要如何使双方都使用同一个 key?这个问题实在很头大,因为如果不靠其它 方法,比如你自己到对方耳边亲口告诉他,或是寄一封挂号信给对方等等。单靠网路的话, 这个 key 是无法不被第三者所知。所以,像 KERBEROS 这类的安全系统(它也是使用 DES 演算法),就必须作一些人工设定(也就是有些动作不能透过网路设定)有个演算法,RSA, 可以解决上述的问题它的做法大概如下:假设资料要由 A 机器传至 B 机器,那,由 B 机器 用乱数决定一个 key,我们称之为 privatekey,这个 key 自始至终都只留在 B 机器里不送出 来然後,由这个 privatekey 计算出另一个 key,我们称之为 publickey。这 个 publickey 的特性 是几乎不可能反演算出 privatekey 来然後将这个 publickey 透过网路丢给 A 机器。A 机器将 资料用这个 publickey 编码,这个编码过的资料一定得使用 privatekey 才解得开然後 A 机器 将编码过的资料透过网路传给 B,B 再用 privatekey 将资料解码这时,如果有第三者窃听资 料时,他只得到 B 传给 A 的 publickey,以及 A 用这个 publickey 编码后的资料没有 privatekey, 第三者根本无法解码所以这个方法确实能防止第三者的窃听。 它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。 算法的名字以发明者的名字命名:Ron Rivest, Adi Shamir 和 Leonard Adleman。但 RSA 的 安全性一直未能得到理论上的证明。它经历了各种攻击,至今未被完全攻破。 RSA 的安全性依赖于大数分解。公钥和私钥都是两个大素数( 大于 100 个十进制位) 的函数。据猜测,从一个密钥和密文推断出明文的难度等同于分解两个大素数的积。 密钥对的产生。选择两个大素数,p 和 q 。计算: n = p * q 然后随机选择加密密钥 e,要 求 e 和 ( p - 1 ) * ( q - 1 ) 互质。最后,利用 Euclid 算 法计算解密密钥 d,满足 e * d = 1 ( mod ( p - 1 ) * ( q - 1 ) ) 其中n 和 d 也要互质。数 e 和 n是公钥,d 是私钥。两个素数 p 和 q 不再需要,应该丢 弃,不要让任何人知道。 加密信息 m(二进制表示)时,首先把 m 分成等长数据块 m1 ,m2,。。。, mi ,块 长 s ,其中 <= n, s 尽可能的 大。对应的密文是: ci = mi^e ( mod n ) ( a ) 解密时作如下计算: mi =ci^d ( mod n ) ( b ) RSA 可用于数字签名,方案是用 ( a ) 式签名, ( b )式验证。具体操作时考虑 到安全性和 m信息量较大等因素,一般是先作 HASH 运算。 RSA 的安全性。 RSA 的安全性依赖于大数分解,但是否等同于大数分解一直未能得 到理论上的证明,因为没有证明破解 RSA 就一定需要作大数分解。假设存在一种无须分解 大数的算法,那它肯定可以修改成为大数分解算法。目前, RSA 的一些变种算法已被证明 等价于大数分解。不管怎样,分解 n 是最显然的攻击方法。现在,人们已能分解多个十进制 位的大素数。因此,模数 n 必须选大一些,因具体适用情况而定。 RSA 的速度。 由于进行的都是大数计算,使得 RSA 最快的情况也比 DES 慢上倍,无 论是软件还是硬件实现。速度一直是 RSA 的缺陷。一般来说只用于少量数据加密。 RSA 的选择密文攻击。 RSA 在选择密文攻击面前很脆弱。一般攻击者是将某一信息作 一下伪装( Blind),让拥有私钥的实体签署。然后,经过计算就可得到它所想要的信息。 实际上,攻击利用的都是同一个弱点,即存在这样一个事实:乘幂保留了输入的乘法结构: ( XM )^d = X^d *M^d mod n 前面已经提到,这个固有的问题来自于公钥密码系统的最有用的特征--每个人都能使用 公钥。但从算法上无法解决这一问题,主要措施有两条:一条是采用好的公钥协议,保证工 作过程中实体不对其他实体任意产生的信息解密,不对自己一无所知的信息签名;另一条是 决不对陌生人送来的随机文档签名,签名时首先使用 One-Way HashFunction 对文档作 HASH 处理,或同时使用不同的签名算法。在中提到了几种不同类型的攻击方法。 RSA 的公共模数攻击。 若系统中共有一个模数,只是不同的人拥有不同的 e 和 d,系 统将是危险的。最普遍的情况是同一信息用不同的公钥加密,这些公钥共模而且互质,那末 该信息无需私钥就可得到恢复。设 P 为信息明文,两个加密密钥为 e1 和 e2,公共模数是 n, 则: C1 = P^e1 mod n C2 = P^e2 mod n 密码分析者知道 n、e1、e2、C1 和 C2,就能得到 P。 因为 e1 和 e2 互质,故用 Euclidean 算法能找到 r 和 s,满足: r * e1 + s * e2 = 1 假设 r 为负数,需再用 Euclidean 算法计算 C1^(-1),则 ( C1^(-1) )^(-r) * C2^s = P mod n 另外,还有其它几种利用公共模数攻击的方法。总之,如果知道给定模数的一对 e 和 d, 一是有利于攻击者分解模数,一是有利于攻击者计算出其它成对的 e’和 d’,而无需分解模 数。解决办法只有一个,那就是不要共享模数 n。 RSA 的小指数攻击。 有一种提高 RSA 速度的建议是使公钥 e 取较小的值,这样会使 加密变得易于实现,速度有所提高。但这样作是不安全的,对付办法就是 e 和 d 都取较大的 值。 RSA 算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。RSA 是被 研究得最广泛的公钥算法,从提出到现在已近二十年,经历了各种攻击的考验,逐渐为人们 接受,普遍认为是目前最优秀的公钥方案之一。RSA 的安全性依赖于大数的因子分解,但 并没有从理论上证明破译 RSA 的难度与大数分解难度等价。即 RSA 的重大缺陷是无法从理 论上把握它的保密性能如何,而且密码学界多数人士倾向于因子分解不是 NPC 问题。RSA 的缺点主要有:A)产生密钥很麻烦,受到素数产生技术的限制,因而难以做到一次一密。 B)分组长度太大,为保证安全性,n 至少也要 600 bits 以上,使运算代价很高,尤其是速 度较慢,较对称密码算法慢几个数量级;且随着大数分解技术的发展,这个长度还在增加, 不利于数据格式的标准化。目前,SET( Secure Electronic Transaction )协议中要求 CA 采 用比特长的密钥,其他实体使用比特的密钥。 首先,找出三个数,其中 p,q 是两个相异的质数,r 是与(p-1)(q-1)互质的数这三 个数便是 privatekey。接著,找出 m,使得 rm==1mod(p-1)(q-1)这个 m 一定存在,因为 r 与(p-1)(q-1)互质,用辗转相除法就可以得到了再来,计算 n=pqm,n 这两个数便是 publickey 编码过程是,若资料为 a,将其看成是一个大整数,假设 a=n 的话,就将 a 表成 s 进位(s<=n,通常取 s=2^t),则每一位数均小于 n,然後分段编码接下来,计算 b==a^mmodn, (0<=b 1; x:x < q,x 为私钥 ; y:y = g^x mod p ,( p, q, g, y )为公钥; H( x ):One-Way Hash 函数。DSS 中选用 SHA( Secure Hash Algorithm )。 p, q, g可由一组用户共享,但在实际应用中,使用公共模数可能会带来一定的威胁。 签名及验证协议如下: 1. P产生随机数 k,k < q; 2.P 计算 r = ( g^k mod p ) mod q s = ( k^(-1) (H(m) + xr)) mod q 签名结果是( m, r, s )。 3. 验证时计算 w = s^(-1)mod q u1 = ( H( m ) * w ) mod q u2 = ( r * w ) mod q v = (( g^u1 * y^u2 ) mod p ) mod q 若 v = r,则认为签名有效。 DSA 是基于整数有限域离散对数难题的,其安全性与 RSA 相比差不多。DSA 的一个重 要特点是两个素数公开,这样,当使用别人的 p 和 q 时,即使不知道私钥,你也能确认它们 是否是随机产生的,还是作了手脚。RSA 算法却作不到这一点。 7.1.5 BLOWFISH 算法 BlowFish算法用来加密64Bit长度的字符串。 BlowFish算法使用两个“盒”——ungigned long pbox[18]和 unsigned long sbox[4,256]。 BlowFish 算法中,有一个核心加密函数:BF_En (后文详细介绍)。该函数输入 64 位信息,运算后,以 64 位密文的形式输出。用 BlowFish 算法加密信息,需要两个过程: 1.密钥预处理 2.信息加密 分别说明如下: 密钥预处理: BlowFish 算法的源密钥——pbox 和 sbox 是固定的。我们要加密一个信息,需要自己选 择一个 key, 用这个 key 对 pbox 和 sbox 进行变换,得到下一步信息加密所要用的 key_pbox 和 key_sbox。具体的变化算法如下: 1)用 sbox 填充 key_sbox 2)用自己选择的 key8 个一组地去异或 pbox,用异或的结果填充 key_pbox。key 可以 循环使用。 比如说:选的 key 是“abcdefghijklmn”。则异或过程为: key_pbox[0]=pbox[0]^abcdefgh key_pbox[1]=pbox[1]^ijklmnab 如此循环,直到 key_box 填充完毕。 3)用 BF_En 加密一个全 0 的 64 位信息,用输出的结果替换 key_pbox[0]和 key_pbox[1]。 i=0 4)用 BF_En 加密替换后的 key_pbox[i],key_pbox[i+1],用输出替代 key_pbox[i+2]和 key_pbox[i+3] 5)i+2,继续第 4 步,直到 key_pbox 全部被替换 6)用 key_pbox[16]和 key_pbox[17]做首次输入(相当于上面的全 0 的输入),用类似的 方法,替换 key_sbox 信息加密。信息加密就是用函数把待加密信息 x 分成 32 位的两部分: xL,xR BF_En 对输入信息进行变换,BF_En 函数详细过程如下: 对于 i=1 至 16 xL=xL^Pi xR=F(xL)^xR 交换 xL 和 xR(最后一轮取消该运算) xR=xR^P17 xL=xL^P18 重新合并 xL 和 xR 把 xL 分成 4 个 8 位分组:a,b,c 和 d 输出为:F(xL)=((((S[1,a]+S[2,b])MOD 4294967296)^s[3,c])+S[4,d])MOD 4294967296 (2 的 32 次方) (2 的 32 次方) 重新合并后输出的结果就是我们需要的密文。 用 BlowFish 算法解密,同样也需要两个过程。 1.密钥预处理 2.信息解密 密钥预处理的过程与加密时完全相同 信息解密的过程就是把信息加密过程的 key_pbox 逆序使用即可。 可以看出,选择不同的 key,用 BlowFish 算法加密同样的信息,可以得出不同的结果。要 破解 BlowFish 算法,就是要得到 BlowFish 算法的 key。所以,使用 BlowFish 算法进行加密, 最重要的也就是 key 的选择以及 key 的保密。其中 key 的选择可以使用 bf_sdk 中的_WeakKey 函数进行检验。 7.1.6 ElGamal 算法 ElGamal 算法既能用于数据加密也能用于数字签名,其安全性依赖于计算有限域上离散 对数这一难题。密钥对产生办法。首先选择一个素数 p,两个随机数, g 和 x,g, x < p, 计算 y = g^x ( mod p ),则其公钥为 y, g 和 p。私钥是 x。g 和 p 可由一组用户共享。 ElGamal 用于数字签名。被签信息为 M,首先选择一个随机数 k, k与 p - 1 互质,计算: a = g^k ( mod p ) 再用扩展 Euclidean 算法对下面方程求解 b: M = xa + kb ( mod p - 1 ) 签名就是( a, b )。随机数 k 须丢弃。 验证时要验证下式: y^a * a^b ( mod p ) = g^M ( mod p ) 同时一定要检验是否满足 1<= a < p。否则签名容易伪造。 ElGamal 用于加密。被加密信息为 M,首先选择一个随机数 k,k 与 p - 1 互质,计算: a = g^k ( mod p ) b = y^k M ( mod p ) ( a, b )为密文,是明文的两倍长。解密时计算 M = b / a^x ( mod p ) ElGamal 签名的安全性依赖于乘法群(IFp)* 上的离散对数计算。素数 p 必须足够大, 且 p-1 至少包含一个大素数,因子以抵抗 Pohlig & Hellman 算法的攻击。M 一般都应采用信 息的 HASH 值(如 SHA 算法)。ElGamal 的安全性主要依赖于 p 和 g,若选取不当则签名容 易伪造,应保证 g 对于 p-1 的大素数因子不可约。D。Bleichenbache“GeneratingElGamal Signatures Without Knowing the Secret Key”中提到了一些攻击方法和对策。ElGamal 的一个不 足之处是它的密文成倍扩张。 美国的 DSS(Digital Signature Standard)的 DSA(Digital Signature Algorithm)算法是 经 ElGamal 算法演变而来。 7.3 破解密码基础 俗话说磨刀不误砍柴工,要学习软件破解技术,首先要有一定的基础知识:汇编语言。 你不需要很精通汇编语言编程,只要能知道各条指令的作用及相关的基础知识就可以了。当 然,如果你对汇编语言编程比较熟悉的话,对于你的破解学习会很有好处的。虽然现在已经 进入 WINDOWS 时代,汇编语言也从最基本 8086 汇编演变到了复杂的 Win32 汇编,但是 对于解密来说,并无必要去学习 Win32 编程,8086 汇编语言足以胜任破解的需要。 就像修理电器要用万用表一样,纵然你技术再怎么高明,没有工具的帮忙也是枉然: 1.我们最重要的破解工具自然是鼎鼎大名的Softice(WIN95/98 版、WIN NT版)了,这 是个动态跟踪调试工具,任何想要破解的人都必须学会用它,我们决大部分的解密工作都是 在Softice下完成的。另外一个可供选择的动态调试工具是Trw2000,中国人自己编写的,功 能和用法和Softice都差不多。如今有些软件专门针对Softice做了一些防范,碰到这种情况我 们就不得不借助于Trw2000 了。 2.WINDOWS下的软件解密有个好处,就是任何程序都逃脱不了动态跟踪。但有时候 我们也可以利用静态分析工具来帮助我们快速的找到软件破解的突破口;或者是在解密的动 态跟踪过程中,被狡猾的程序搞得晕头转向、摸不着头绪的时候,我们也许能根据对程序的 静态分析来获取破解信息。静态分析工具推荐Win32DASM黄金版,这是个Win32 反汇编程 序,能够将应用程序反编译为汇编源程序,并能提供很多相关的信息,是解密的重要工具。 3.通常软件破解分为两类:完全破解和暴力破解,所谓完全破解就是指通过获取正确 的注册码的破解方式,而有些软件的破解并不能通过获取注册码得到(比如只是显示未注册 画面),或者是很难得到正确的注册码(软件太狡猾,隐藏得比较深),此时我们就需要通过 修改程序代码来达到破解的目的。修改应用程序代码需要专用的十六进制编辑器,比如 UltraEdit、Hex WorkShop、Hiew等。本人比较喜欢用Hiew,因为它不但支持十六进制编辑, 同时也支持反汇编及直接的汇编程序修改,简单小巧,使用非常方便。 4.现在有很多的软件都用压缩工具压缩了(也就是通常说的加壳了),如ACDSEE、THE BAT等。当我们用Win32DASM进行反汇编之后,根本就发现不了任何有意义的信息;如果 你想暴力破解这种软件,当用Hiew打开程序进行编辑的时候你会发觉找不到要修改的地方。 遇到这种情况你就应该用文件检测工具看看程序是否有壳,是什么样的壳。知道了是什么壳, 然后才可以去壳,接着才能修改程序。文件类型侦测工具很多,如gtw这个工具,它是 WINDOWS界面,使用起来较为方便。 在进行软件的破解、解密以及计算机病毒分析工作中,一个首要的问题是对软件及病毒 进行分析。这些软件都是机器代码程序,对于它们分析必须使用静态或动态调试工具,分析 跟踪其汇编代码。 一、从软件使用说明和操作中分析软件 欲破解一软件,首先应该先用用这软件,了解一下功能是否有限制,最好阅读一下软件 的说明或手册,特别是自己所关心的关键部分的使用说明,这样也许能够找点线索。 二、静态反汇编 所谓静态分析即从反汇编出来的程序清单上分析,从提示信息入手进行分析。目前,大 多数软件在设计时,都采用了人机对话方式。所谓人机对话,即在软件运行过程中,需要由 用户选择的地方,软件即显示相应的提示信息,并等待用户按键选择。而在执行完某一段程 序之后,便显示一串提示信息,以反映该段程序运行后的状态,是正常运行,还是出现错误, 或者提示用户进行下一步工作的帮助信息。为此,如果我们对静态反汇编出来的程序清单进 行阅读,可了解软件的编程思路,以便顺利破解。 常用的静态分析工具是 W32DASM、IDA 和 HIEW 等。 三、动态跟踪分析 虽然从静态上可以了解程序的思路,但是并不可能真正了解地了解软件的细节,如静态 分析找不出线索,就要动态分析程序,另外,碰到压缩程序,静态分析也无能为力了,只能 动态分析了。所谓动态分析是利用 SOFTICE 或 TRW2000 一步一步地单步执行软件。为什 么要对软件进行动态分析呢?这主要是因为: 1.许多软件在整体上完成的功能,一般要分解成若干模块来完成,而且后一模块在执 行时,往往需要使用其前一模块处理的结果,这一结果我们把它叫中间结果。如果我们只对 软件本身进行静态地分析,一般是很难分析出这些中间结果的。而只有通过跟踪执行前一模 块,才能看到这些结果。另外,在程序的运行过程中,往往会在某一地方出现许多分支和转 移,不同的分支和转移往往需要不同的条件,而这些条件一般是由运行该分支之前的程序来 产生的。如果想知道程序运行到该分支的地方时,去底走向哪一分支,不进行动态地跟踪和 分析是不得而知的。 2.有许多软件在运行时,其最初执行的一段程序往往需要对该软件的后面各个模块进 行一些初始始化工作,而没有依赖系统的重定位。 3.有许多加密程序为了阻止非法跟踪和阅读,对执行代码的大部分内容进行了加密变 换,而只有很短的一段程序是明文。加密程序运行时,采用了逐块解密,逐块执行和方法, 首先运行最初的一段明文程序,该程序在运行过程中,不仅要完成阻止跟踪的任务,而且还 要负责对下一块密码进行解密。显然仅对该软件的密码部分进行反汇编,不对该软件动态跟 踪分析,是根本不可能进行解密的。 由于上述原因,在对软件静态分析不行的条件下,就要进行动态分析了。哪么如何有效 地进行动态跟踪分析呢?一般来说有如下几点: 1.对软件进行粗跟踪 所谓粗跟踪,即在跟踪时要大块大块地跟踪,也就是说每次遇到调用 CALL 指令、重复操 作指令 REP。循环操作 LOOP 指令以及中断调用 INT 指令等,一般不要跟踪进去,而是根 据执行结果分析该段程序的功能。 2.对关键部分进行细跟踪 对软件进行了一定程度的粗跟踪之后,便可以获取软件中我们所关心的模块或程序段,这 样就可以针对性地对该模块进行具体而详细地跟踪分析。一般情况下,对关键代码的跟踪可 能要反复进行若干次才能读懂该程序,每次要把比较关键的中间结果或指令地址记录下来, 这样会对下一次分析有很大的帮助。软件分析是一种比较复杂和艰苦的工作,上面的几点分 析方法,只是提供了一种基本的分析方法。要积累软件分析的经验需要在实践中不断地探索 和总结。 7.3.1解密标准操作流程 我们一般认为解密标准操作流程是: 一、拿到一个软件,我们 cracker 首先要做的是检测壳的类型,并知道软件是用什么语 言编制的。 如果象以前的单追码也可以直接用 sice,不过现在大部分都用国产的 trw 了,所以 要 脱壳。 二、然后我们就要进行脱壳工作,有脱壳机的就自动,没有的就手动。相关工具可以在 网络上找到。 三、根据编制语言来选择调试工具来分析,一般用 wdasm 或 ida,也可以用其他的,一 般 vb 用 smartcheck wktvbde 等,delphi 和 borland c 用 dede。 vc 应该什么都可以用了, 它的反编译可以看到大部分未加密文字,把相关地址和代码找到后,同时拷贝到一个文本文 档中,以备自己参考,可以边追踪边记录,这是个好习惯。然后用动态调试工具(sice、trw、 ollydbg 等)来动态追踪。 四、如果程序有 crc 就要解除。 五、破解结束后,根据结果(序列号、补丁、注册机等)选择发布过程,和别人交流。 7.3.2 脱壳技术 首先我们应该先明白“壳”的概念。在一些计算机软件里有一段专门负责保护软件不被 非法修改或反编译的程序。它们一般都是先于程序运行,拿到控制权,然后完成它们保护软 件的任务。我们把这样的程序称为“壳”了。 也就是说,运行加壳程序时, 用户执行的实际上是这个外壳的程序,而这个外壳程序 负责把用户原来的程序在内存中解压缩,并把控制权交还给解开后的真正的程序,由于一切 工作都是在内存中运行,用户根本不知道也不需要知道其运行过程,只要执行起来没有变化 就好。也许有些人担心这些解压缩的工作会给程序带来额外的运行时间,但实际上所有的可 执行文件都要读到内存中去执行,文件小了,从计算机硬盘上读到内存的时间自然也少了, 两下相抵,实际上用户并不会感觉程序慢了多少。脱壳的就是把在内存中真正还原的程序抓 取下来,修正后变成可执行的文件。 我们下面来看看用工具自动脱壳的方法: 1.用 TYP 等侦测工具侦测你的软体是被哪一种“壳”给加密了。 2.用 Procdump 1.5 等 剥壳机器剥壳,Procdump 1.5 可剥许多已知壳、未知的 for win32 的壳。 7.3.4 代码知识 首先,我们要知道数据的几种格式,这几种格式是:字节(BYTE)、字(WORD)和 双字(DOUBLE WORD),或者说是 8 位、16 位和 32 位储存方式。字节也就是 8 位方式能 储存 0~255 的数字;字或说是 16 位储存方式能储存 0~65535 的数;双字即 32 位方式能储 存 0~4294967295 的数。在计算机中数据以字节为基本的储存单位,每个字节被赋予一个编 号,以确定各自的位置。这个编号 我们就称为地址。在需要用到字或双字时,计算机用连 续的两个字节来组成一个字,连续的两个字组成一个双字。而一 个字或双字的地址就是它 们的低位字节的地址。现在我们常用的 Windows 操作系统中,地址是用一个 32 位的二进制 数表示的。而在以前我们用到内存地址时,总是用一个 8 位的 16 进制数来表示它。 二进制 和十六进制又是怎样一回事呢? 简单说来,二进制数就是一种只有 0 和 1 两个数码,每满 2 则进一位的计数进位法。同 样,16 进制就是每满十六就进一位的计数进位法。16 进制有 0--F 十六个数字,它为表示十 到十五的数字采用了 A、B、C、D、E、F 六个数字,它们和十进制的对应关系是:A 对应 于 10,B 对应于 11,C 对应于 12,D 对应于 13,E 对应于 14,F 对应于 15。而且,16 进 制数和二进制数间有一个简单的对应关系,那就是;四位二进制数相当于一位 16 进制数。 比如,一个四位的二进制数 1111 就相当于 16 进制的 F,1010 就相当于 A。 看了以上内容 大家对数据的存贮和数据的对应关系应该有所来了解了。 我们现在来看看代码优化的: 代码优化的目标当然是体积小和速度快,但是在通常的情况下二者就象鱼和熊掌一样不 能得兼,我们通常寻找的是这二者的折中,究竟应该偏向何方,那就得具体看我们的实际需 要。 但有些常识是我们应该牢记的,下面就结合我们最常遇到的具体情况来谈一下: 1. 寄存器清 0 2.测试寄存器是否为 0 3.测试寄存器是否为 0FFFFFFFFh 4.置寄存器为 0FFFFFFFFh 5.寄存器清 0 并移入低字数值 6.关于 push,是着重代码体积的优化,因为寄存器操作总要比内存操作要快。 7.乘法 当 eax 已经放入被乘数,要乘 28h,如何来写? 1) mov ecx, 28h ;5 bytes mul ecx ;2 bytes 好一点的写法如下: 2) push 28h ;2 bytes pop ecx ;1 byte mul ecx ;2 bytes 下面这个更好: 3) imul eax, eax, 28h ;3 bytes 8.字符串操作 你如何从内存取得一个字节呢? 速度快的方案: 1) mov al/ax/eax, [esi] ;2/3/2 bytes inc esi ;1 byte 代码小的方案: 2) lodsb/w/d ;1 byte 9.我们来看复杂带内的例子 假设你有一个 DWORD 表,ebx 指向表的开始,ecx 是指针,你想给每个 doword 加 1, 应该如何做呢? 1) pushad ;1 byte imul ecx, ecx, 4 ;3 bytes add ebx, ecx ;2 bytes inc dword ptr [ebx] ;2 bytes popad ;1 byte 其实可以优化一点, 2) inc dword ptr [ebx+4*ecx] ;3 bytes 10.下面是关于病毒重定位优化的。 下面的代码你不应该陌生: 1) call gdelta gdelta: pop ebp sub ebp, offset gdelta 在以后的代码中我们这样使用 delta 来避免重定位问题 lea eax, [ebp + variable] 这样的指令在应用内存数据的时候是不可避免的,如果能优化一下,我门将会得到数倍 收益,打开你的 sice 或者 trw 或者 ollydbg 等调试器,看看: 3) lea eax, [ebp + 401000h] ;6 bytes 假如是下面这样 4) lea eax, [ebp + 10h] ;3 bytes 也就是说如果 ebp 后面变量是 1 字节的话,总的指令就只有 3 字节 修改一下最初的格式变为: 5) all gdelta gdelta: pop ebp 在某些情况下我们的指令就只有 3 字节了,可以节省 3 字节,让我们看看: 6) lea eax, [ebp + variable - gdelta] ;3 bytes 其实还有很多其他的技巧。 7.3.5 汇编语言 我们前面提到汇编语言是破解的基础,这里我们简单介绍一些汇编的知识: 汇编语言用一些助记符来代替 0 和 1 的多种组合,也就是各个指令,这样的话,从一定 程度上来说,比机器语言方便了许多,但是,汇编也同样不方便,同样写起来不方便,而且 后期维护同样不方便,再加上人们慢慢地需要写一些更大的程序,在这样的情况下,高级语 言就被人发明了出来,就是我们今天用的 Basic、pascal、C、C++等等等等,这些语言的出 现,一下了使程序的开发难度大大减低了,以前用汇编要很长时间才能开发出来的程序,现 在只需要很短的时间且很轻松的就可以完成了,但是汇编还是有它先天的优势的,因为其与 CPU 内部的指令一一对应,所以在一些特殊的场合,必须由汇编来实现,比如访问硬件的 端口、写病毒等等。而且生成的可执行文件效率巨高,且生成的可执行文件很小,写小程序 是很方便的,而且用汇编写注册机,是件很轻松的事。 我们知道计算机只识别 0 和 1,那么,所有存储在计算机上的文件,也都是以二进制的 形式存放的,当然也包括可执行文件了。 所以,我们只要找一个十六进制编辑器比如 Ultra Edit 什么的,就可直接打开并查看可执行文件了,当然,其中就包括可执行文件的代码了。 但是这些东西看起来很难看明白,但是我们可以利用相应的软件,可以将这些十六进制数值 转换为相应的汇编代码,这样的话,我们就可以对别人的软件进行分析了。这就是所谓的逆 向分析了。 所以,如果我们找到软件计算注册码的部分,并对其进行分析,弄懂它的计算方法,那 么我们就破解成功了。当然,你也可以将此计算过程还原为任意一个你所熟悉的编程语言, 那么,编译后的这个程序,就叫做注册机,它的功能就是计算某一特定软件的注册码。 上面提到的分析方法,就是所谓的静态分析,此类分析常用的工具有 W32DASM、IDA 和 HIEW 等。静态分析,顾名思义,就是只通过查看软件的反汇编代码来对软件进行分析。 一般如果只是想暴破软件,只进行静态分析就够了。但要想真正的弄清注册算法,一般还是 要进行动态分析的,即能过调试器来一边执行程序一边进行分析。 我们再来看看 CPU 的构成,CPU 的任务就是执行存放在存储器里的指令序列。为此, 除要完成算术逻辑操作外,还需要担负 CPU 和存储器以及 I/O 之间的数据传送任务。早期 的 CPU 芯片只包括运算器和控制器两大部分。到了后来,为了使存储器速度能更好地与运 算器的速度相匹配,又在芯片中引入了高速缓冲存储器。除了高速缓冲存储器之外的组成, 大体上可以分为 3 个部分: 1.算术逻辑部件 ALU(arithmetic logic unit)用来进行算术和逻辑运算。这部分与我们 的关系不太大,我们没必要管它。 2.控制逻辑。同样与我们的关系不大。 3.这个才是最最重要的。工作寄存器,它在计算机中起着重要的作用,每一个寄存器相 当于运算器中的一个存储单元,但它的存取速度却贼快贼快,比存储器要快很多了。它用来 存放计算过程中所需要的或所得到的各种信息,包括操作数地址、操作数及运算的中间结果 等。下面我们专门的介绍这些寄存器。 在介绍之前,有必要说点儿基础性的知识。现在的寄存器一般是 32 位的,在 CPU 中, 一个二进制位被看作是一位,八位就是一个字节,在内存中,就是以字节为单位来在存储信 息的,每一个字节单元给以一唯一的存储器地址,称为物理地址,到时候访问相应的内存, 就是通过这个地址。八个二进制位都能表达些什么呢?可以表达所有的 ASCII 码,也就是 说一个内存单元可以存储一个英文字符或数字什么的,而中文要用 Unicode 码来表示,也就 是说两个内存单元,才能装一个汉字。十六位就是两个字节这不难理解吧,当然,也有三十 二位六十四位的,三十二位叫做双字,六十四位就叫做四字。 首先,介绍通用寄存器。 一共八个,分别是 EAX、EBX、ECX、EDX、ESP、EBP、 EDI、ESI。 其中,EAX—EDX 这四个寄存器又可称为数据寄存器,你除了直接访问外,还 可分别对其高十六位和低十六位进行访问。它们的低十六位就是把它们前边儿的 E 去掉, 即 EAX 的低十六位就是 AX。而且它们的低十六位又可以分别进行八位访问,也就是说, AX 还可以再进行分解,即 AX 还可分为 AH(高八位)AL(低八位)。其它三个寄存器请 自行推断。这样的话,你就可以应付各种情况,如果你想操作的是一个八位数据,那么可以 用 MOV AL (八位数据)或 MOV AH (八位数据),如果你要操作的是一个十六位数据, 可以用 MOV AX (十六位数据)三十二位的话,就用 MOV EAX (三十二位数据)。这四 个寄存器,主要就是用来暂时存放计算过程中所用的操作数、结果或其它信息。 而 ESP、 EBP、EDI、ESI 这四个呢,就只能用字来访问,它们的主要用途就是在存储器寻址时,提 供偏移地址。因此,它们可以称为指针或变址寄存器。这就是说此时 EBX 中装的是一个内 存地址,而真正要访问的,就是那那个内存单元中所存储的值。在这几个寄存器中,ESP 称为堆栈指针寄存。堆栈是一个很重要的概念,它是以“后进先出“方式工作的一个存储区, 它必须存在于堆栈段中,因而其段地址存放于 SS 寄存器中。它只有一个出入口,所以只有 一个堆栈指针寄存器。ESP 的内容在任何时候都指向当前的栈顶。堆栈时候,它的基址开始 于一个高地址,然后每当有数据入栈,它就向低地址的方向进行存储。相应的入栈指令是 PUSH。每当有数据入栈,ESP 就跟着改变,总之,它永远指向最后一个压入栈的数据。之 后,如果要用压入堆栈的数据,就用出栈指令将其取出。相应的指令是 POP,POP 指令执 行后,ESP 会加上相应的数据位数。 特别是现在到了 Win32 系统下面,堆栈的作用更是不可忽视,API 所用的数据,均是靠 堆栈来传送的,即先将要传送的数据压入堆栈,然后 CALL 至 API 函数,API 函数会在函 数体内用出栈指令将相应的数据出栈。然后进行操作。以后你就会知道这点的重要性了。许 多明码比较的软件,一般都是在关键 CALL 前,将真假两个注册码压入栈。然后在 CALL 内出栈后进行比较。所以,只要找到个关键 CALL,就能在压栈指令处,下 d 命令来查看真 正的注册码。 另外还有 EBP,它称为基址指针寄存器,它们都可以与堆栈段寄存器 SS 联用来确定堆 栈中的某一存储单元的地址,ESP 用来指示段顶的偏移地址,而 EBP 可作为堆栈区中的一 个基地址以便访问堆栈中的信息。ESI(源变址寄存器)和 EDI(目的变址寄存器)一般与 数据段寄存器 DS 联用,用来确定数据段中某一存储单元的地址。这两个变址寄存器有自动 增量和自动减量的功能,可以很方便地用于变址。在串处理指令中,ESI 和 EDI 作为隐含的 源变址和目的变址寄存器时,ESI 和 DS 联用,EDI 和附加段 ES 联用,分别达到在数据段 和附加段中寻址的目的。 接下来,介绍一下专用寄存器,所谓的专用寄存器,有两个,一个是 EIP,一个是 FLAGS。 我们先来说这个 EIP,可以说,EIP 算是所有寄存器中最重要的一个了。它的意思就是指令 指针寄存器,它用来存放代码段中的偏移地址。在程序运行的过程中,它始终指向下一条指 令的首地址。它与段寄存器 CS 联用确定下一条指令的物理地址。当这一地址送到存储器后, 控制器可以取得下一条要执行的指令,而控制器一旦取得这条指令就马上修改 EIP 的内容, 使它始终指向下一条指令的首地址。可见,计算机就是用 EIP 寄存器来控制指令序列的执行 流程的。 那些跳转指令,就是通过修改 EIP 的值来达到相应的目的的。再接着我们说一下这个 FLAGS,标志寄存器,又称 PSW(program status word),即程序状态寄存器。这一个是存 放条件标志码、控制标志和系统标志的寄存器。 其实我们根本不需要太多的去了解它,你目前只需知道它的工作原理就成了,我们来看 个例子: Cmp EAX,EBX ;用 EAX 与 EBX 相减 JNZ 00470395 ;不相等的话,就跳到这里; 这两条指令很简单,就是用 EAX 寄存器装的数减去 EBX 寄存器中装的数。来比较这 两个数是不是相等,当 Cmp 指令执行过后,就会在 FLAGS 的 ZF(zero flag)零标志位上 置相应值,如果结果为 0,也就是他们两个相等的话,ZF 置 1,否则置 0。其它还有 OF(溢 出标志)SF(符号标志)CF(进位标志)AF(辅助进位标志)PF(奇偶标志)等。 最后要介绍的就是段寄存器了。这部分寄存器一共六个,分别是 CS 代码段,DS 数据 段,ES 附加段,SS 堆栈段,FS 以及 GS 这两个还是附加段。 其实现在到了 Win32 环境下, 段寄存器以经不如 DOS 时代那样重要了。 相信现在大家对 CPU 已经有了个大概的了解了。我们接下来就再讲一讲一些常用的汇 编指令。 CMP A,B 比较 A 与 B 其中 A 与 B 可以是寄存器或内存地址,也可同时是两个寄存器, 但不能同都是内存地址。这个指令太长见了,许多明码比较的软件,就用这个指令。 MOV A,B 把 B 的值送给 A 其中,A 与 B 可是寄存器或内存地址,也可同时是两个寄 存器,但不能同都是内存地址。 Xor a,a 异或操作,主要是用来将 a 清空 LEA 装入地址,例如 LEA DX,string 将字符的地址装入 DX 寄存器 PUSH 压栈 POP 出栈 ADD 加法指令 格式:ADD DST,SRC 执行的操作:(DST)<-(SRC)+(DST) SUB 减法指令 格式:SUB DST,SRC 执行的操作:(DST)<-(DST)-(SRC) MUL 无符号乘法指令 格式: MUL SRC 执行的操作:字节操作(AX)<-(AL)* (SRC); 操作(DX,AX)<-(AX)*(SRC);双字操作:(EDX,EAX)<-(EAX)*(SRC) DIV 无符号除法指令 格式:DIV SRC 执行的操作:字节操作:16 们被除数在 AX 中, 位除数为源操作数,结果的 8 位商在 AL 中,8 位余数在 AH 中。表示为: (AL)<-(AX)/(SRC)的商,(AH)<-(AX)/(SRC)的余数。字操作:32 位被 除数在 DX,AX 中。其中 DX 为高位字,16 位除数为源操作数,结果的 16 位商在 AX 中, 16 位余数在 D 中。表示为:(AX)<-(DX,AX)/(SRC)的商,(DX)<-(DX,AX)/ (SRC)的余数。 双字操作:64 位的被除数在 EDX,EAX 中。其中 EDX 为高位双字;32 位除数为源操作数,结果的 32 位商在 EAX 中,32 位余数在 EDX 中。表示为:(EAX)<- (EDX,EAX)/(SRC)的商,(EDX)<-(EDX,EAX)/(SRC)的余数。 NOP 无作用, 可以用来抹去相应的语句,这样的话, CALL 调用子程序,你可以把它当作高级语言中的 过程来理解。 控制转移指令: JE 或 JZ 若相等则跳 JNE 或 JNZ 若不相等则跳 JMP 无条件跳 JB 若小于则跳 JA 若大于则跳 JG 若大于则跳 JGE 若大于等于则跳 JL 若小于则跳 JLE 若小于等于则跳 总的来说,以上几个,都是比较常见的,需要掌握,但需要掌握的绝不止这几个,其它 的指令希望你能在私下里再了解一下,可以找相应的教程来看。 7.3.6 Windows 程序 我们知道 Win32 是一个非常深奥的系统,我们这里只是讲一些关于 Windows 程序运作 的原理: Windows 为什么叫 Windows,相信所有用过的朋友都可以明白,那桌面上一个一 个的窗口,就是它名字的由来。也就是这一个又一个窗口的出现,使计算机的使用一下子简 单了很多。 Windows 之所以好用,除了不用背很多的命令外,一个原因就是因为它本身提供了大量 的标准 Windows GUI 函数。所以对于用户,面对的是同一套标准的窗口,对这些窗口的操 作都是一样的,所以使用不同的应用程序时无须重新学习操作。不用像当年在 DOS 下面那 样一安装新程序,就要马上看帮助,看说明。 而 Windows GUI 函数,只不过是微软提供给程序开发人员的 API(Application Programming Interface 应用编程接口)中的一小部分而以。Windows API 是一大组功能强大 的函数,它们本身驻扎在 Windows 中供人们随时调用。这些函数的大部分被包含在几个动 态链接库(DLL)中,譬如:kernel32.dll、 user32.dll 和 gdi32.dll。 Kernel32.dll 中的函数 主要处理内存管理和进程调度;user32.dll 中的函数主要控制用户界面;gdi32.dll 中的函数 则负责图形方面的操作等等。 你可能听说过 API 函数,如果你不太清楚到底是怎么一回事的话,我们这里简单解释 一下。大家也许会想,Windows 中的那一个又一个窗口是怎么画出来的呢?你如果用 VB、 Delphi 编过程序,你有没有想过你写的程序中的那些窗口是怎么形成的?是控件变成的。其 实所有我们用的 Windows 下的程序,都是通过调用一个又一个的 Windows API 来执行相应 任务的,没有 API,我们的程序什么也做不了。用 VB、Delphi 以及 MFC 的朋友也许会说 我根本没有调用什么 API 啊。其实这些 API 都是由你所用的开发环境自动进行相应的转换 的。比如说你用 Delphi 新建一程序,什么也不用动就直接按 F9 来运行它,是不是出现一个 空白的窗体?这就是个标准的 Windows 程序,它有 Windows 程序所具有的一切特征,如最 大化按钮、最小化按钮、关闭按钮等等,你可以通过鼠标来移动它。 但是如果你想用 VC++或 MASM32 来写这样一个程序,那么你有两种方法,在 VC++ 中,你可以用 MFC 或直接调用 API,而在 MASM32 中,你就只有直接调用 API 这一种方 法。所谓直接调用 API,就是指所有的操作都通过最原始的 API 来完成。通过直接调用 API 来生成这样一个程序,你必须要先注册窗口类(除非您使用 Windows 预定义的窗口类,如 MessageBox 或 dialog box);然后产生窗口;然后在桌面显示窗口(除非您不想立即显示它); 然后刷新窗口客户区; 是有点麻烦,如果你想真正的让这个程序能正常地运行下来,还要再加入以下步骤: 1.你要得到您应用程序的句柄。2.窗体显示后就进入无限的获取窗口消息的循环。3. 如 果有消息到达,由负责该窗口的窗口回调函数处理。4. 如果用户关闭窗口,进行退出处理。 上面这此步骤,都需要调用相应的 API 来完成。比如说得到程序的句柄用 GetModuleHandle 注册窗口类用 RegisterClass 或 RegisterClassEx; 注册后,还要用 CreateWindowEx 函数来生成相应窗口,而后用 ShowWindow 来显示它,之后还会用 UpdateWindow 来更新客户区等等等等。 上面说的这些,只不过是 API 中的一很小的部分,这才几个,真正的 API 有成百上千 个,包括对系统各个方面进行的操作。没有 API,你的程序什么也干不了。我们现在明白了 一件事,那就是我们所用的程序,无时无刻都在调用着系统中的各种各样的 API 函数。 其实 Windows 中的 API,就相当于当年 DOS 系统中的系统功能调用,及中断 21。只不 过在数量上和功能上,都是 DOS 系统功能调用所不及的。 下面我们介绍几个常用的 API 函数: MessageBox 显示一信息对话框 MessageBoxEx 显示一信息对话框 MessageBoxIndirect 显示一定制信息对话框 (以上这三个,可以用来中断那些错误提示,比如说你注册码输入错误了,程序就可能 通过这几个函数中的一个,来提示你错误) GetDlgItemInt 得指定输入框整数值 GetDlgItemText 得指定输入框输入字符串 GetDlgItemTextA 得指定输入框输入字符串 (软件可以用这三个来得到用户输入的注册码) GetLocalTime 得当前本地时间 GetSystemTime 得当前系统时间 (软件可以用这两个来判断软件是否过期) RegQueryvalueA 获取一个项的设置值 RegQueryvalueExA 获取一个项的设置值 RegSetvalueA 设置指定项或子项的值 RegSetvalueExA 设置指定项的值 (如果软件用注册表存储注册信息的话,那么这几个也许会有用) 上面讲的,只是几个平时比较常见的,更多请参见看雪以前的教程或 Windows 开发人员手 册。 最后,我们还要介绍一个重要的函数,它就是 hmemcpy。 它是一个非常简单的函数。 只完成一项非常非常基本的任务,就是把数据从一个地方复制到另一个地方。应用程序本身 并不调用它。但是大部分 API 函数却非常频繁地调用它。所以,它也叫万能函数。平时你 可能都不知道有这么个东西,但是断起程序来却非常管用。但目前的 Windows2000 和 Windows xp 下,却没有这个函数了,与之相应的是一个叫 memcpy 的函数,虽然功能与其 相同,但是用 memcpy 根本就断不下什么来。 7.3.7 破解原理 一般学习破解的有三个阶段: 初级,修改程序,用 ultraedit 等工具修改 exe 文件,称暴力破解,简称爆破。 中级,追出软件的注册码 。 高级,写出注册机 我们先说这爆破。所谓爆破,就是指通过修改可执行文件的源文件,来达到相应的目的。 举个例子,比如说某共享软件,它比较用户输入的注册码,如果用户输入的,跟它通过用户 名(或其它)算出来的注册码相等的话(也就是说用户输入的注册码正确了),那么它就会 跳到注册成功的地方去,否则就跳到出错的地方去。我们只要找到这个跳转指令,把它修改 就可以了。 我们再说一下虚拟地址和偏移量转换的问题,在 SoftICE 和 W32Dasm 下显示的地址值 是所谓的内存地址(memory offset),或称之为虚拟地址(Virual Address,VA)。而十六进 制工具里,如:Hiew、Hex Workshop 等显示的地址就是文件地址,称之为偏移量(File offset) 或物理地址(RAW offset)。 所以当我们要通过那些十六进制工具来对可执行文件中的相应指令进行修改的话,先要 找到它的 File offset。我们没有必要去使用那些专门的转换工具,在 W32Dasm 中就有这个 功能,比如说你 W32Dasm 中来到 0045123D 处,在 W32Dasm 界面下方的状态栏中就会出 现该条指令的虚拟地址和偏移地址,即@:0045123D @offset 0005063Dh 后面的这个 0005063Dh 就是相应的偏移地址。我们得到该地址后,便可用 UltraEdit 等十六进制工具来 对可执行文件进行修改了。比如使用 UltraEdit,你先用 UltraEdit 打开该可执行文件,然后 按 Ctrl+G,接着输入你得到的偏移地址,就可以来到其相应的机器码处。 所谓的机器码。就是你看到的那些个十六进制数据了。它们与汇编指令是一一对应的。 以下这几个是爆破时要用到的: JZ=74;JNZ=75;JMP=EB;Nop=90 爆破的时候,只要对以上机器码进行相应的修改就行了,比如第一种情况的时候,可以 将 74 修改为 EB,即将 JZ 修改为 JMP。而第二种情况,责需将 75 修改为 90,即将 JNZ 修 改为 Nop。 我们下面来看看怎么找出注册码。刚才我们说爆破的时候不提到过关键 CALL。一般情 况下,这个关键 CALL 就是对两个注册码(一个是软件自身通过你的注册名或机器什么的 计算出来的正确的注册码,令一个就是你输入的错误的注册码)进行比较。我们知道,CALL 之前一般会把所用到的数据先放到一个地方,CALL 过去的时候再从这些地方把先前放入的 数据取出来,进行相应的处理。这个关键 CALL 也是这样,在 CALL 之前,一般会把那两 个注册码放到堆栈或某个寄存器中。我们只要在调试器中,单步执行到该 CALL,在未进去 之前通过 CALL 之前的指令判断其将正确的和不正确的注册码放到哪里了。然后再用相应 指令进行查看就成了。 下面列出两个最常见的情况: no.1 mov eax [ ] 这里可以是地址,也可以是其它寄存器 mov edx [ ] 同上,该条指令也可以是 pop edx call 00?????? 关键 call test eax eax jz(jnz)或 jne(je) 关键跳转 在关键 CALL 之前,软件会把两个注册码分别放入 eax 和 edx 中,你只要在 CALL 处 下 d eax 或 d edx 就能看到正确的注册码了。 no.2 mov eax [ ] 这里可以是地址,也可以是其它寄存器 mov edx [ ] 同上,该条指令也可以是 pop edx call 00?????? 关键 call jne(je) 关键跳转 以上两种情况最为常见,当然还有其他情况。 7.3.10 注册码炼成过程 我们Crack一个软件的最终目的,是对其进行相应的分析,搞懂它的注册算法并写出注 册机,这样才算是成功的Crack了一个软件。其实分析一个软件的注册算法,这其中包括了 一些技巧性方面的东西以及必要的经验,我们以网际快车FlashGet举个例子: 首先运算一下这个软件,其会自动生成机器码,我们这里是rkeUMwpNv5xZ。我们以调 试器Ollydbg来作讲解,我们还是先用RW2000,用 bpx hmemcpy点确定后会被拦,pmodule后 返回到 0040432f处,我们就从这里开始,打开Ollydbg, 我们用Ollydbg载入,在反汇编代 码处(即左上方那个子窗口中)按Ctrl+G,输入 0040432f,回车后便来到了这里。 我们按 F2 在这里下断,接着按 F9 来运行程序,在注册处输入 CHINA Cracking Group Suunb 后按确定会被 Ollydbg 断下来,大概跑跑看看,我们来看看贴出反汇编代码 0040432F |. 8D4C24 10 LEA ECX,DWORD PTR SS:[ESP+10] 00404333 |. 6A 05 PUSH 5 00404335 |. 51 PUSH ECX 00404336 |. 68 E8030000 PUSH 3E8 0040433B |. 8BCE MOV ECX,ESI 0040433D |. E8 10050000 CALL 00404342 |. 8BC8 MOV ECX,EAX 00404344 |. E8 7D060000 CALL 00404349 |. 8D5424 18 LEA EDX,DWORD PTR SS:[ESP+18] 0040434D |. 6A 05 PUSH 5 0040434F |. 52 PUSH EDX 00404350 |. 68 E9030000 PUSH 3E9 00404355 |. 8BCE MOV ECX,ESI 00404357 |. E8 F6040000 CALL 0040435C |. 8BC8 MOV ECX,EAX 0040435E |. E8 63060000 CALL 00404363 |. 8D4424 20 LEA EAX,DWORD PTR SS:[ESP+20] 00404367 |. 6A 05 PUSH 5 00404369 |. 50 PUSH EAX 0040436A |. 68 EA030000 PUSH 3EA 0040436F |. 8BCE MOV ECX,ESI 00404371 |. E8 DC040000 CALL 00404376 |. 8BC8 MOV ECX,EAX 00404378 |. E8 49060000 CALL 0040437D |. 8D4C24 28 LEA ECX,DWORD PTR SS:[ESP+28] 00404381 |. 6A 05 PUSH 5 00404383 |. 51 PUSH ECX 00404384 |. 68 EB030000 PUSH 3EB 00404389 |. 8BCE MOV ECX,ESI 0040438B |. E8 C2040000 CALL 00404390 |. 8BC8 MOV ECX,EAX 00404392 |. E8 2F060000 CALL 00404397 |. 8B7C24 68 MOV EDI,DWORD PTR SS:[ESP+68] 0040439B |. 33DB XOR EBX,EBX 0040439D |. 33C9 XOR ECX,ECX 0040439F |. 8D04BF LEA EAX,DWORD PTR DS:[EDI+EDI*4] 004043A2 |. 8D0480 LEA EAX,DWORD PTR DS:[EAX+EAX*4] 004043A5 |. 8D3480 LEA ESI,DWORD PTR DS:[EAX+EAX*4] 004043A8 |. C1E6 02 SHL ESI,2 执行后 ESI 的值为 5DC,及十进制数 1500 004043AB |> 0FBE440C 50 /MOVSX EAX,BYTE PTR SS:[ESP+ECX+50] <--ESP+ECX+50 就是机器码在内存中的地址(首次执行到 这里明 ECX 为 0,得到的就是机器码的第一位,第二次到这里时 ECX 会加上 1,得到的是 第二位) 004043B0 |. 03C6 |ADD EAX,ESI <--与 ESI 相加,也就是加上 1500 004043B2 |. BD 3E000000 |MOV EBP,3E <--EBP 置 3E,及十进制数 62 004043B7 |. 99 |CDQ <--扩展... 004043B8 |. F7FD |IDIV EBP <--EAX 中装的机器码的第 1 or 2 or 3 or 4 位与 1500 的和与 62 相除 004043BA |. 0FBE440C 54 |MOVSX EAX,BYTE PTR SS:[ESP+ECX+54] <--ESP+ECX+54 得到机器码的第 5 位(还记的 ESP+ECX+50 中装的是第一位吗?首次执行到这里明 ECX 为 0,得到的就是机器码的第 5 位,第二次到 这里时 ECX 会加上 1,得到的是第 6 位。) 004043BF |. 03C6 |ADD EAX,ESI <--同样加上 1500 004043C1 |. 8A92 E4704000 |MOV DL,BYTE PTR DS:[EDX+4070E4] <--重 要的地方来了。此时 EDX 中装的是前面的第 1 or 2 or 3 or 4 位机器码加上 1500 后再除以 62 的余数,那 4070E4 处是什么呢?如果在 TRW2000 中,我们用 d 004070E4 就可以看到,在 Ollydbg 中,我们可以在左下角处按 Ctrl+G 来输入相应的内存地址,这样的话就可以看到了。 我们会发现从 4070E4 开始,装的是一串字符,依次是 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ。呵呵明白 什么意思了吗?4070E4 处指的是 0,那 4070E4 加上 edx 中装的余数后的内存地址中装的便 是当前机器码所对应的注册码。(如余数为 5,那 么 从 4070E4 处的 0 开始往后数第 5 个字符 就是了)该条指令执行过后就会把相应的注册码装入 dl 中。 004043C7 |. 88540C 30 |MOV BYTE PTR SS:[ESP+ECX+30],DL <--将 机器码的第 1 or 2 or 3 or 4 所对应的注册码装入 ESP+ECX+30 处 004043CB |. 99 |CDQ <--前边儿得到的 第 5 or 6 or 7 or 8 位机器码扩展 004043CC |. F7FD |IDIV EBP <--同样除以 62 004043CE |. 8A82 E4704000 |MOV AL,BYTE PTR DS:[EDX+4070E4] <-- 与 004043C1 处作用相同,不用我多说了吧,就是得到当前机器码的对应注册码 004043D4 |. 88440C 38 |MOV BYTE PTR SS:[ESP+ECX+38],AL <--装 入 ESP+ECX+38 处 004043D8 |. 0FBE440C 58 |MOVSX EAX,BYTE PTR SS:[ESP+ECX+58] <-- 得到机器码的第 9 or 10 or 11 or 12 位 004043DD |. 03C6 |ADD EAX,ESI <--与 1500 相 加 004043DF |. 99 |CDQ <--扩展.... 004043E0 |. F7FD |IDIV EBP <--除以 62 004043E2 |. 0FBE440C 5C |MOVSX EAX,BYTE PTR SS:[ESP+ECX+5C] <-- 得到机器码的第 13 or 14 or 15 or 16 位 004043E7 |. 03C6 |ADD EAX,ESI <--与 1500 相加 004043E9 |. 8A92 E4704000 |MOV DL,BYTE PTR DS:[EDX+4070E4] <--前 边的第 9 or 10 or 11 or 12 位所对应的注册码 004043EF |. 88540C 40 |MOV BYTE PTR SS:[ESP+ECX+40],DL <--装 入 ESP+ECX+40 处 004043F3 |. 99 |CDQ <--扩展 004043F4 |. F7FD |IDIV EBP <--除以 62 004043F6 |. 41 |INC ECX <--ECX 加 1 004043F7 |. 83F9 04 |CMP ECX,4 <--看 ECX 是否 为 4(前边儿是一次计算四位的嘛,第一次计算第 1、5、9、13 位,第二次是 2、6、10、14. 等等 ) 004043FA |. 8A82 E4704000 |MOV AL,BYTE PTR DS:[EDX+4070E4] <--得 到前边的第 13 or 14 or 15 or 16 位机器码所对应的注册码 00404400 |. 88440C 47 |MOV BYTE PTR SS:[ESP+ECX+47],AL <--装 入 ESP+ECX+47 处 00404404 |.^7C A5 \JL SHORT LIAOCACH.004043AB <--ECX 小于 4 就从头再来一遍(直到 16 位机器码都计算完为止) 00404406 |. 8B35 AC524000 MOV ESI,DWORD PTR DS:[<&MSVCRT.atoi>] ; MSVCRT.atoi 0040440C |. 8D4C24 10 LEA ECX,DWORD PTR SS:[ESP+10] 00404410 |. 51 PUSH ECX ; /s 00404411 |. 885C24 38 MOV BYTE PTR SS:[ESP+38],BL ; | 00404415 |. 885C24 40 MOV BYTE PTR SS:[ESP+40],BL ; | 00404419 |. 885C24 48 MOV BYTE PTR SS:[ESP+48],BL ; | 0040441D |. 885C24 50 MOV BYTE PTR SS:[ESP+50],BL ; | 00404421 |. FFD6 CALL ESI ; \atoi 00404423 |. 83C4 04 ADD ESP,4 00404426 |. 83F8 01 CMP EAX,1 00404429 |. 75 3C JNZ SHORT LIAOCACH.00404467 0040442B |. 8D5424 18 LEA EDX,DWORD PTR SS:[ESP+18] 0040442F |. 52 PUSH EDX 00404430 |. FFD6 CALL ESI 00404432 |. 83C4 04 ADD ESP,4 00404435 |. 83F8 01 CMP EAX,1 00404438 |. 75 2D JNZ SHORT LIAOCACH.00404467 0040443A |. 8D4424 20 LEA EAX,DWORD PTR SS:[ESP+20] 0040443E |. 50 PUSH EAX 0040443F |. FFD6 CALL ESI 00404441 |. 83C4 04 ADD ESP,4 00404444 |. 83F8 01 CMP EAX,1 00404447 |. 75 1E JNZ SHORT LIAOCACH.00404467 00404449 |. 8D4C24 28 LEA ECX,DWORD PTR SS:[ESP+28] 0040444D |. 51 PUSH ECX 0040444E |. FFD6 CALL ESI 00404450 |. 83C4 04 ADD ESP,4 00404453 |. 83F8 01 CMP EAX,1 00404456 |. 75 0F JNZ SHORT LIAOCACH.00404467 00404458 |. 5F POP EDI 00404459 |. 5E POP ESI 0040445A |. 5D POP EBP 0040445B |. B8 FEFFFFFF MOV EAX,-2 00404460 |. 5B POP EBX 00404461 |. 83C4 54 ADD ESP,54 00404464 |. C2 0400 RETN 4 00404467 |> 8D7424 30 LEA ESI,DWORD PTR SS:[ESP+30] <--正确的注 册码的前 4 位的地址装入 ESI 中,执行到这里时我们就可以看到正确的注册的前 4 位了,在 TRW2000 or SoftICE 中可以用 d ESP+30 来查看而在 Ollydbg 中什么都不用做就可以在左上 方反汇编代码区与左下内存区中间的那个小窗体中看见,在 TRW2000 中下过 D 指令后按 Alt+上下键翻几下,就可以看到所有的注册码了(0063F5E0-0063F5E3 是前 4 位, 0063F5E8-0063F5EB 是 5-8 位,0063F5F0-0063F5F3 是 9-12 位,0063F5F8-0063F5FB 是最后 4 位,而你输入的注册码的内存地址:0063F5C0-0063F5C3 是前 4 位,0063F5C8-0063F5CB 是 5-8 位,0063F5D0-0063F5D3 是 9-12 位,0063F5D8-0063F5DB 是最后 4 位,机器码存放 的地址是 0063F6000-0063F60F) 0040446B |. 8D4424 10 LEA EAX,DWORD PTR SS:[ESP+10] <--你输入 的注册码的前 4 位的地址装入 EAX 中 0040446F |> 8A10 /MOV DL,BYTE PTR DS:[EAX] <--得到你输 入的注册码的第 1 位或第 3 位(EAX 中的值到了后边儿会加上 2,这样再执行到这里时得 到的就是第 3 位了) 00404471 |. 8ACA |MOV CL,DL <--传入 cl 中 00404473 |. 3A16 |CMP DL,BYTE PTR DS:[ESI] <--与正确的注 册码的第 1 位或第 3 位比较(ESI 中的值会与 EAX 中的值一起改变) 00404475 |. 75 1C |JNZ SHORT LIAOCACH.00404493 <--不相等就跳 走 00404477 |. 3ACB |CMP CL,BL <--CL与 BL 比较, BL 中的值为 00000000(也就是空啦),这条指令有什么用呢?其实很简单了,每 4 位注册码 的后面都会再跟一个空值,也就是如你在内存中可以看到 1234.那个.就是空值,明白过来了 吧,等到前 4 位都被测试过了,cl 中就会装入.也就是 00000000,到时就可以在后面跳走了。 00404479 |. 74 14 |JE SHORT LIAOCACH.0040448F <--如果 CL 中 的值为零(即 4 位已经全部比较过了),就跳走。 0040447B |. 8A50 01 |MOV DL,BYTE PTR DS:[EAX+1] <--EAX+1 后 得到的会是你输入的注册码的第 2 位或者第 4 位(视 EAX 的值而定) 0040447E |. 8ACA |MOV CL,DL <--传入 CL 00404480 |. 3A56 01 |CMP DL,BYTE PTR DS:[ESI+1] <--与正确的注 册码的第 2 位或第 4 位比较(ESI 的值会与 EAX 一起改变) 00404483 |. 75 0E |JNZ SHORT LIAOCACH.00404493 <--不相等就跳 走 00404485 |. 83C0 02 |ADD EAX,2 <--EAX 加上 2,这样 的话待会儿再跳到 0040446F 处时,再得到的就是你输入的注册码的第 3 位了 00404488 |. 83C6 02 |ADD ESI,2 <--同上,ESI 加上 2 后再跳到 0040446F 处重新再来一遍时就会得到正确的注册码的第 3 位 0040448B |. 3ACB |CMP CL,BL <--再次比较 CL 是 否为空 0040448D |.^75 E0 \JNZ SHORT LIAOCACH.0040446F <--不为空就 再跳到 0040446F 处,来继续比较前 4 位中的 1、3 两位 0040448F |> 33C0 XOR EAX,EAX <--1-4 位全部比 较完后会跳到这里 00404491 |. EB 05 JMP SHORT LIAOCACH.00404498 00404493 |> 1BC0 SBB EAX,EAX 00404495 |. 83D8 FF SBB EAX,-1 00404498 |> 3BC3 CMP EAX,EBX 0040449A |. 0F85 AB000000 JNZ LIAOCACH.0040454B 004044A0 |. 8D7424 38 LEA ESI,DWORD PTR SS:[ESP+38] <--与上面的 大体相同嘛,将正确注册码的 5-8 位的内存地址装入 ESI 中 004044A4 |. 8D4424 18 LEA EAX,DWORD PTR SS:[ESP+18] <--你输入 的注册码的 5-8 位的内存地址装入 EAX 中 004044A8 |> 8A10 /MOV DL,BYTE PTR DS:[EAX] <--得到你输 入的注册码的第 5 or 7 位(道理我相信你一定已经明白了) 004044AA |. 8ACA |MOV CL,DL <--再装入 CL 中 004044AC |. 3A16 |CMP DL,BYTE PTR DS:[ESI] <--与正确的注 册码的第 5 or 7 位比较 004044AE |. 75 1C |JNZ SHORT LIAOCACH.004044CC <--不相等就 跳走 004044B0 |. 3ACB |CMP CL,BL <--与 BL 中的 00000000 比较,看 5-8 位是否已经全部比较完毕 004044B2 |. 74 14 |JE SHORT LIAOCACH.004044C8 <--是的话就跳 走 004044B4 |. 8A50 01 |MOV DL,BYTE PTR DS:[EAX+1] <--得到你输 入的注册码的第 6 or 8 位 004044B7 |. 8ACA |MOV CL,DL <--装入 CL 004044B9 |. 3A56 01 |CMP DL,BYTE PTR DS:[ESI+1] <--与正确的注 册码的第 6 or 8 位比较 004044BC |. 75 0E |JNZ SHORT LIAOCACH.004044CC <--不正确就 跳走 004044BE |. 83C0 02 |ADD EAX,2 <--EAX 加 2,这样 做的目的相信大家已经知道了 004044C1 |. 83C6 02 |ADD ESI,2 <--ESI 也加上 2 004044C4 |. 3ACB |CMP CL,BL <--比较 CL 是否为 空 004044C6 |.^75 E0 \JNZ SHORT LIAOCACH.004044A8 <--不是就跳 回去再来一遍 004044C8 |> 33C0 XOR EAX,EAX <--5-8位全部比 较完后全跳到这里 004044CA |. EB 05 JMP SHORT LIAOCACH.004044D1 004044CC |> 1BC0 SBB EAX,EAX 004044CE |. 83D8 FF SBB EAX,-1 004044D1 |> 3BC3 CMP EAX,EBX 004044D3 |. 75 76 JNZ SHORT LIAOCACH.0040454B 004044D5 |. 8D7424 40 LEA ESI,DWORD PTR SS:[ESP+40] <--将正确的 注册码的 9-12 位的内存地址装入 ESI 004044D9 |. 8D4424 20 LEA EAX,DWORD PTR SS:[ESP+20] <--你输入 的 004044DD |> 8A10 /MOV DL,BYTE PTR DS:[EAX] <--得到你输 入的注册码的第 9 or 11 位 004044DF |. 8ACA |MOV CL,DL <--装入 CL 004044E1 |. 3A16 |CMP DL,BYTE PTR DS:[ESI] <--与正确的注 册码的第 9 or 11 位比较 004044E3 |. 75 1C |JNZ SHORT LIAOCACH.00404501 <--不对便跳 走 004044E5 |. 3ACB |CMP CL,BL <--看 CL 是否为空, 即看 9-12 位是否全部比较完毕 004044E7 |. 74 14 |JE SHORT LIAOCACH.004044FD <--是的话跳走 004044E9 |. 8A50 01 |MOV DL,BYTE PTR DS:[EAX+1] <--得到你输 入的注册码的第 10 or 12 位 004044EC |. 8ACA |MOV CL,DL <--装入 CL 004044EE |. 3A56 01 |CMP DL,BYTE PTR DS:[ESI+1] <--与正确的注 册码的第 10 or 12 位比较 004044F1 |. 75 0E |JNZ SHORT LIAOCACH.00404501 <--不相等就跳 走 004044F3 |. 83C0 02 |ADD EAX,2 <--EAX 加 2 004044F6 |. 83C6 02 |ADD ESI,2 <--ESI 加 2 004044F9 |. 3ACB |CMP CL,BL <--看是否全部比较 完毕 004044FB |.^75 E0 \JNZ SHORT LIAOCACH.004044DD <--没有就跳 回去再来一遍 004044FD |> 33C0 XOR EAX,EAX <--9-12 位全部比 较完毕后会跳到这里 004044FF |. EB 05 JMP SHORT LIAOCACH.00404506 00404501 |> 1BC0 SBB EAX,EAX 00404503 |. 83D8 FF SBB EAX,-1 00404506 |> 3BC3 CMP EAX,EBX 00404508 |. 75 41 JNZ SHORT LIAOCACH.0040454B 0040450A |. 8D7424 48 LEA ESI,DWORD PTR SS:[ESP+48] 0040450E |. 8D4424 28 LEA EAX,DWORD PTR SS:[ESP+28] 00404512 |> 8A10 /MOV DL,BYTE PTR DS:[EAX] 00404514 |. 8ACA |MOV CL,DL 00404516 |. 3A16 |CMP DL,BYTE PTR DS:[ESI] 00404518 |. 75 1C |JNZ SHORT LIAOCACH.00404536 0040451A |. 3ACB |CMP CL,BL 0040451C |. 74 14 |JE SHORT LIAOCACH.00404532 0040451E |. 8A50 01 |MOV DL,BYTE PTR DS:[EAX+1] 00404521 |. 8ACA |MOV CL,DL 00404523 |. 3A56 01 |CMP DL,BYTE PTR DS:[ESI+1] 00404526 |. 75 0E |JNZ SHORT LIAOCACH.00404536 00404528 |. 83C0 02 |ADD EAX,2 0040452B |. 83C6 02 |ADD ESI,2 0040452E |. 3ACB |CMP CL,BL 00404530 |.^75 E0 \JNZ SHORT LIAOCACH.00404512 00404532 |> 33C0 XOR EAX,EAX <--全部通过后来到这里 00404534 |. EB 05 JMP SHORT LIAOCACH.0040453B 00404536 |> 1BC0 SBB EAX,EAX 00404538 |. 83D8 FF SBB EAX,-1 0040453B |> 3BC3 CMP EAX,EBX 0040453D |. 75 0C JNZ SHORT LIAOCACH.0040454B 0040453F |. 8BC7 MOV EAX,EDI 00404541 |. 5F POP EDI 00404542 |. 5E POP ESI 00404543 |. 5D POP EBP 00404544 |. 5B POP EBX 00404545 |. 83C4 54 ADD ESP,54 00404548 |. C2 0400 RETN 4 软件的注册码是这样计算出来的,机器码中的各个字符的 ASCII 码加上 1500 后除以 62 的余数在密码表中对应的字符,就是相应的注册码。 比如说我这里的机器码为 xn2urkeUMwpNv5xZ,x 的 ASCII 码为 78(十进制 120) 78+5DC 的值为 654(即 1620) 接着用 1620 除以 3E(62)得商 26 余 8,好的,我们从“密码 表”0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 的开始 处向后数 8 下,就会到了 8 这个字符,这就是 x 对应的注册码。 好的,我们现在给出 Delphi 的注册机(我仍将其写为函数的形式): function KeyGen(Name: String): String; var S:String[16]; P:String; Key:String; i,N,Z:integer; begin P:='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; if Length(Name)<16 then Result:='机器码必须为 16 位...' else begin S:=Name; for i:=1 to 16 do begin N:=Ord(S[i]); N:=N+1500; Z:= N mod 62; Z:=Z+1; Key:=Key+P[Z]; end; Result:=Key; end; end; 7.4 密码设置技巧 在使用 QQ,邮箱等工具的时候,你注意到了自己的密码是否安全,如何才能最大程序 的预防盗窃密码的黑客?这里有十种密码,看看的是不是也符合其中的条件,如果符合的话, 你将有可能成为下一次被盗的目标。 第一种、密码和用户名相同。如:用户名和密码都是 11111。几乎所有盗取密码的人, 都会以用户名作为破解密码的突破口。 第二种、密码为用户名中的某几个邻近的数字或字母。如:用户名为 nihao520,密码为 ihao 或 520。如果您的用户名是字母和数字组合,如:nihao520,那么别人要盗取您的密码 时,肯定会以用户名中的字母或数字来试密码。 第三种、密码为连续或相同的数字。如 123123 等。几乎所有黑客软件,都会从连续或 相同的数字开始试密码。如:先试 111、111......到 9999999999,然后再试 123、321、234、 1234......如果您的密码是 111111、123456 或 654321,甚至用不着黑客软件也能在片刻试出。 第四种、密码为连续或相同的数字,如 aaaaaaa 等。字母虽然比数字多,但是先试相同 的字母如 abcd,再试连续的字母如 aaaaa,黑客软件所用时间也不会太多。 第五种、将用户名颠倒或加前后缀作为密码。如用户名为 test,密码为 test123、aaatest、 tset 等。以用户名 test 为例,黑客软件在尝试使用 test 作为密码之后,还会试着使用诸如 test123、test1、tset、tset123 等作为密码,只要是你想得到的变换方法,黑客软件也会想得 到,它破解这种口令,几乎不需要时间。 第六种、使用姓氏的拼音作为密码。在不少黑客软件中,百家姓往往都被一一列出,并 放在字典的前列。只需片刻即可破解您的密码。以姓氏或姓名的拼音作为密码还存在一种危 险:想盗您密码的人如果探听到您的真实姓名,就很有可能用您姓名中的拼音组合来试密码。 第七种、使用自己或亲友的生日作为密码。由于表示月份的只有 1~12 可以使用,表示 日期的也只有 1-31 可以使用,表示日期的肯定 19xx 或 xx,因此表达方式只有 100×12×31×2 =74400 种,即使考虑到年月日共有六种排列顺序,一共也只有 74400×6=446400 种。按普 通计算机每秒搜索 3~4 万种的速度计算,破解您的密码最多只需 10 秒。 第八种、使用常用英文单词作为密码。黑客软件一般都有一个包含 10 万~20 万个英文 单词及相应组合的字典库。如果您的密码在这个库中,那么即使字典库中有 20 万单词,再 考虑到一些 DES(数据加密算法)的加密运算,每秒搜索 1800 个,也只需要 110 秒。 第九种、使用 8 位以下的数字作为密码。数字只有 10 个,8 位数字组成方式只有 10 的 8 次方=100,000,000 种,按普通计算机每秒搜索 3~4 万种的速度计算,黑客软件只需要 不到 3 小时就可以破解您的密码了。 第十种、使用 5 位以下的小写字母加数字作为口令。小写字母加数字一共 36 位,组合 方式只有 36 的 5 次方=60466176 种可能性,按普通的计算机每秒搜索 3~4 万种的速度计 算,黑客软件只需要 25 分钟就可以破解密码。 Windows 的密码设置技巧 每个 Windows 用户都会设置密码,但在默认情况下,Windows 对密码的“监管”不是 很严,比如它没有对密码的最小长度进行限制,许多用户出于方便的考虑,往往将密码设置 得比较短,这样做是很不安全的。通过以下两种方法,我们可以进一步加强 Windows 密码 的安全性。 1.限制密码最小长度 打开注册表编辑器,依次展开 HKEY_LOCAL_MACHINE\SOFTWARE\ Microsoft \ Windows \ CurrentVersion \ policies \ Network 分支,在右侧窗口新建字符串值 “MinPwdLen”,并设置其值为适当大小如 6(必须大于等于 0 小于等于 8)。以后设置密码时, 如输入密码的位数小于 6,系统就会提示我们增加密码的位数,保护系统安全。 2.禁止别人更改密码 通常我们可以通过控制面板的“密码”选项对密码进行修改。不过你也可以禁止这项功能,以 防止别人进行破坏。打开注册表编辑器,依次展开 HKEY_LOCAL_MACHINE\SOFTWARE \Microsoft\Windows\CurrentVersion\policies\Network 分支,新建“DWORD 值”为 “DisablePwdCaching”,并将其值设置为 1,则控制面板“密码”选项中的“更改 Windows 密 码”按钮将无法使用。
还剩44页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 10 金币 [ 分享pdf获得金币 ] 0 人已下载

下载pdf

pdf贡献者

glaxia

贡献于2012-02-05

下载需要 10 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf