主要思路就是提供者持有密钥,通过RSA加密客户机标识或时间标识,再通过Base64加密成不太难看的注册码,然后分发给客户机。
客户机解Base64后,通过持有的公钥来验证注册码是否与本机标识或时间标识相符。
一、 生成公密钥
RSACryptoServiceProvider cryptor = new RSACryptoServiceProvider();
File.WriteAllText(\"PrivateKey.xml\", cryptor.ToXmlString(true));
File.WriteAllText(\"PublicKey.xml\", cryptor.ToXmlString(false));
为了方便长期保存这里就直接存入文件了。
为了避免客户机公钥丢失,我比较倾向于将公钥直接编译到验证程序中,但是这样也就意味着如果更换了密钥,老的验证程序就验不了新生成的注册码了。
二、 生成注册码
static string CreateRegCode(string mac, DateTime date)
{
RSACryptoServiceProvider cryptor = new RSACryptoServiceProvider();
cryptor.FromXmlString(File.ReadAllText(\"PrivateKey.xml\"));
string signature = String.Format(\"[{}][{}]\", mac, date.ToString(\"yyyy-MM-dd\"));
byte[] regCodeBytes = cryptor.SignData(
Encoding.UTF.GetBytes(signature),
\"SHA\");
return Convert.ToBaseString(regCodeBytes);
}
这个方法是通过加密MAC和日期的组合来生成注册码,需要注意几点:
1.参数中的MAC是客户机的地址2.第四行的文件是上一步生成的密钥文件
3.由于只考虑验证,所以客户机还必须知道参数中的date
三、 验证注册码
static bool Verify(string regCode)
{
const string PUBLIC_KEY = \"\";
try
{
RSACryptoServiceProvider cryptor = new RSACryptoServiceProvider();
cryptor.FromXmlString(PUBLIC_KEY);
byte[] signedData = Convert.FromBaseString(regCode);
bool today = cryptor.VerifyData(
Encoding.UTF.GetBytes(String.Format(\"[{}][{}]\", DateTime.Now.ToString(\"yyyy-MM-dd\"))),
\"SHA\", signedData);
bool machineToday = cryptor.VerifyData(
Encoding.UTF.GetBytes(String.Format(\"[{}][{}]\", MAC, DateTime.Now.ToString(\"yyyy-MM-dd\"))),
\"SHA\", signedData);
bool forever = cryptor.VerifyData(
Encoding.UTF.GetBytes(String.Format(\"[{}][{}]\", MAC, Environment.MachineName)),
\"SHA\", signedData);
return today || machineToday || forever;
}
catch
{
return false;
}
}
这个方法验证了三种类型的注册码:当天可用、本机当天可用和永久可用。
需要注意:
1.第三行的公钥就是第一步的PublicKey.xml中的内容
2.十四和十七行的MAC是客户机的物理地址,至于怎么获取不是本文的重点,请各位看官自行百度
3.考虑到客户机填写的注册码有可能不是合法的Base64文本,需要捕获解析时异常
其实RSACryptoServiceProvider也提供了解密的方法,这样就可以验证更多种类的验证码了。
本文地址:https://www.stayed.cn/item/9107
转载请注明出处。
本站部分内容来源于网络,如侵犯到您的权益,请 联系我