萌新学习DSA加密应用——MacroRxxxxxxx注册码解析
本帖最后由 S.L.Kagura 于 2019-10-25 16:54 编辑# 前言
前两天逛论坛,浏览了大佬的[汉化发布贴](https://www.52pojie.cn/thread-979534-1-3.html)
看说明是C#写的,顿时来了兴趣,主要想学习一下注册码的算法,看看有没有很有意思的东西。
在下萌新一枚,初学C#,有分析错误和记录错误的地方还请不吝赐教!
# 工具准备
dnSpy-netcore-win32 v6.0.5
待分析软件 v5.8
# 分析
首先用dnSpy载入,直接看到大大的Key名称空间,里面还有Encryption、LiceneseChecker、SerialGeneration这种十分照顾在下的名称,瞬间心态良好。
接着我们找到注册码的验证函数VerifyKey,VerifyKey这个函数还有一个重载函数,记得不要看错。这个过程很简单,就算不会分析,随便点点都能找到,所以寻找过程不是本次的重点。
接着我们看一下验证过程,上来第一件事直接正则匹配,如果是XXXX-XXXX-XXXX-XXXX这种格式的验证码,直接限制到期日在2014年1月31日。
这里我们肯定不会用旧版的注册码,往下会看到首先程序尝试用Base64转换,转换成功则继续,失败则返回。(关键点标记①)
紧接着,程序提取了转换后验证码的最后2字节,并组合在一起转换成整数型num。(关键点标记②)
这还没有完,程序通过C#的位运算符&,匹配num的最后一位数字是否是1,并返回布尔值。如果为真,则有更新限制。(关键点标记③)
之后,程序通过右移位运算符>>,把num的最后一位去掉,剩余的数就是注册码的有效月数。注意一点,此处的移位操作是对num变量的二进制型进行操作。如num的十进制型值为12,用二进制表示就是00001100,向右移动一位后变成00000110,再转换成十进制表示就是6。(关键点标记④)
最后,程序再把去除掉有效期和更新限制的注册码,以及转换为字节组型的用户名,作为参数一并传给DSA函数进行验证。(关键点标记⑤)
DSA算法是一种常用的不对称加密算法,在下对这个算法原理学习还不到位,这里就不讲解原理了。虽然原理上有区别,但是其应用方法和RSA是一样的,私钥加密明文得到密文,通过公钥解密密文得到明文。通过分析代码,你可以更深层次了解和学习到相关的内容,十分的迷思。这或许是作者的福利,咱也不知道,咱也不敢问...
# 复原
了解清楚的注册码的验证过程,我们只需要逆推关键点操作,就可以得到注册码生成的过程了。
public static string MakeSerial(string username)
{
// 有效期和更新限制
DateTime expirationDate = new DateTime(2099, 12, 31);
bool releaseLimited = false;
// DSA加密用户名(关键点标记⑤)
DSACryptoServiceProvider dcsp = new DSACryptoServiceProvider(keySize);
dcsp.FromXmlString(priKeyString);
byte[] bMessage = new UTF8Encoding().GetBytes(username);
byte[] serial = dcsp.SignData(bMessage);
dcsp.PersistKeyInCsp = false;
// 生成有效期更新限制代码
int countMonth = (expirationDate.Year - DateTime.Now.Year) * 12 + (expirationDate.Month - DateTime.Now.Month); //计算月份(关键点标记④)
byte[] value = IntToDoubleByte(countMonth * 2 + Convert.ToInt32(releaseLimited)); //添加更新限制(关键点标记③)
// 组合(关键点标记②)
serial = CopyByteArray(serial, value);
// Base64编码(关键点标记①)
return Convert.ToBase64String(serial);
}
顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶 谢谢大佬分享 了解清楚的注册码的验证过程,我们只需要逆推关键点操作,就可以得到注册码生成的过程 支持楼主学习学习 学习一下,谢谢 Have a Look At!!!!! 学习了。感谢楼主:lol 感谢!!! 没有接触过C#
页:
[1]
2