我正在使用Brett给出的这个例子:
这样做:
public static bool VerifyLicenseKey(string applicationGuid)
{
Console.WriteLine("G: " + applicationGuid);
var appSettings = AppSettings.GetInstance();
if (appSettings == null)
{
return false;
}
var hwinfo = HardwareInfo.GetHardwareSerial();
Console.WriteLine("h: " + hwinfo);
Console.WriteLine("a: " + applicationGuid);
var currentSerial = Crypto.EncryptStringAES(hwinfo, applicationGuid);
Console.WriteLine("c: " + currentSerial);
Console.WriteLine("o: " + appSettings.LicenseSerialNumber);
if (currentSerial == appSettings.LicenseSerialNumber)
{
return true;
}
return false;
}
}
GetHardwareSerial
和applicationGuid
每次都会回来,但是当我拨打EncryptStringAES
时,它不是。
我使用错误的课程吗?是不是每次都假设一样?
如果没有,有人有一个更好的例子,其中加密值是相同的吗?
答案 0 :(得分:4)
您的“加密”实际上只是模糊处理而且不太难以绕过。 所有人都需要知道的是你的应用程序guid(可能存储为公共)以及获取相同硬件ID的方法(你可能没有写那个并且很容易找到)。
当然,您希望保护工作有多难取决于您的软件的价值或大批量,因此简单的混淆可能就足够了。忘记AES,你需要的是哈希算法,例如SHA或MD5,你可以将你的应用程序guid,硬件号,用户名等散列在一起并存储哈希。对于大多数典型用户来说,这足以起到威慑作用。
如果您坚持要求难以破解的保护,您需要的是数字签名和激活程序。请参阅RSACryptoServiceProvider。
基本上,您创建了一个知道您的私钥的服务,并将匹配的公钥放在您的软件中。然后从您的软件中使用HardwareInfo调用该服务以及您要验证的任何其他信息,服务对其进行签名并返回签名哈希。
在客户端使用公钥后,您可以使用公钥检查签名,即使信息可以以纯文本格式存储,也无法轻易地重新创建签名。
另外check this question了解更多信息。
答案 1 :(得分:3)
您引用的算法使用RijndaelManaged class,它似乎使用其IV
property的默认值,这是(非常正确)自动设置为新的随机值您创建一个新实例(参见文档)。
因此,每次都会得到不同的结果。 (例如,你会在Wikipedia上找到有关IV的目的的更多信息。)
答案 2 :(得分:0)
是的,大多数AES加密都是非确定性的(并且有充分的理由)它不适合您,但由于您只想比较加密结果而您实际上并不想解密,我建议使用{{ 3}}而不是。