• 标 题:shareware的作者们,你们可以使用微软的CRYPTOAPI来加密注册码或者关键的程序代码! (911字)
  • 作 者:1212
  • 时 间:2000-9-5 14:22:20
  • 链 接:http://bbs.pediy.com

Cryptography API在MSDN中有简单介绍。

如果用CRYPTOAPI来生成注册码,则你的注册码在目前根本无人能够破解,即不知道加密密钥的人是无法得出一个正确的注册码的,就象The BAT!一样。但是只这样做的话别人还是可以强行修改程序中的JNZ、JZ指令使得软件成为注册版本。

如果发布软件之前将关键的指令代码(比如只有注册用户才能使用的那段代码)用CRYPTOAPI加密,加密密钥和解密密钥都不在软件的发行版中出现(即使使用调试器也无法在程序的发行包中得到)。用注册码作为解密密钥,即当用户输入注册码之后,程序用该注册码(或该注册码的一部分)作为解密密钥试图去解开事先加密好的那段代码,如果是注册用户,则解开的代码是可以执行的,否则解开后得到的只是一堆垃圾,只要一运行就必然出非法操作。这样该软件可以说是无法破解的了。

为了使得不同的注册用户都可以解开同一个发行包,解密密钥应该是固定的一个串,即注册码是个常数串,不包含注册用户的信息。这样一旦已注册用户得到该注册码,就可以任意传播,这是该方法的缺陷。没有好的方法可以在注册码中嵌入用户名。

  • 标 题:对该方法的补充 (1千字)
  • 作 者:guest
  • 时 间:2000-9-5 15:20:39

刚才又想到一个如何在注册码中嵌入名字的方法。

由于用来解密程序代码的那个密钥是个常数串,所以不可能在该串中嵌入用户名,但可以将其作为注册码的第一部分,而注册码的第二部分由如下的方法得到:

      RSA encrypt        RSA encrypt
用户名------------->中间值--------------->注册码的第二部分

这样就在注册码的第二部分中嵌入了用户信息。在判断注册码的第二部分的时候,是这样判断的:
if (RSA_encrypt(用户名) == RSA_decrypt(注册码第二部分))
{
    registered user;
}
else
{
    pirate copy;
}
上述的加密和解密可以使用不同的密钥。

同时,上述if语句所在的函数的代码事先已经加密过,没有注册的用户无法得到正确的注册码的第一部分,自然无法得到上述if语句的机器码的明文。即使有某个注册用户在网上散播了其注册码的第一部分(他若散播注册码的第二部分就可以知道他是谁,除非他使用盗窃的信用卡帐号),除了软件作者也无人能满足上面的if语句的条件,只有在内存中动态patch上面的if语句及相关代码。为了提高patch的难度,可以采用动态分配内存的方法,将解压出来的代码放在动态分配得到的堆中执行,这样解压出来的代码的偏移地址是浮动的,patch的难度大大增加。