C# 从序列号生成激活密钥

C# 从序列号生成激活密钥,c#,.net,asp.net,vb.net,algorithm,C#,.net,Asp.net,Vb.net,Algorithm,我有具有唯一序列号(字符串递增)的设备,例如:AS1002和AS1003 我需要找出一个算法,为每个序列号生成一个唯一的激活密钥 最好的方法是什么 谢谢 (这必须离线完成)如果您的设备具有某些安全内存,而这些内存无法通过连接编程器或其他设备来读取-您可以存储一些关键代码,然后使用任何哈希算法,如MD5或SHA-1/2,通过以下方式生成哈希: HASH(PUBLIC_SERIALNUMBER + PRIVATE_KEYCODE) SERIALNUMBER+KEYCODE对应存储在本地数据库中 以

我有具有唯一序列号(字符串递增)的设备,例如:AS1002和AS1003

我需要找出一个算法,为每个序列号生成一个唯一的激活密钥

最好的方法是什么

谢谢


(这必须离线完成)

如果您的设备具有某些安全内存,而这些内存无法通过连接编程器或其他设备来读取-您可以存储一些关键代码,然后使用任何哈希算法,如
MD5
SHA-1/2
,通过以下方式生成哈希:

HASH(PUBLIC_SERIALNUMBER + PRIVATE_KEYCODE)
SERIALNUMBER+KEYCODE对应存储在本地数据库中

以这种方式:(离线

  • 客户打电话给您并询问激活码
  • 您需要特定设备的序列号
  • 然后在本地数据库中按给定的序列号搜索密钥码,并生成激活码(即使使用MD5,只要密钥码私自存储在数据库中,这将是安全的)
  • 客户端将激活码输入设备,设备能够生成哈希 通过自己的序列号和键码,然后与用户输入的激活码进行比较

若设备上有安全内存(如智能卡),则可以通过存储激活码来简化此过程。通过这种方式,您可以保留自己的SerialCode-ActivationCode对数据库。

到目前为止,最安全的方法是拥有一个(序列号、激活密钥)对的集中数据库,并让用户通过internet激活,以便您可以在本地(服务器上)检查密钥


在这个实现中,激活密钥可以是完全随机的,因为它不需要依赖于序列号 -任何生成的密钥都必须能够很容易地输入,这样就消除了一些奇怪的散列,这些字符可能会产生繁琐的字符,尽管这是可以克服的,但这是你应该考虑的问题。 -您所说的操作必须在线完成

首先,无论您如何试图混淆,都无法绝对肯定地说有人无法破译您的密钥生成例程。只需在搜索引擎中查询“破解Xyz软件”

这是一场永远不会结束的长期斗争,因此,将软件作为服务交付,即在线交付,其中制作人对其内容有更多的控制权,并可以明确授权和验证用户。在您的情况下,您希望脱机执行此操作。因此,在您的场景中,将有人将您的设备连接到某个系统,您打算编写此例程的附带软件将根据设备v/s用户输入的序列号进行检查

根据@sll的回答,考虑到您请求的离线性质。不幸的是,您最好生成一组随机代码,并在用户呼叫时验证它们

这是从另一个SO答案中借用的答案,我还添加了数字

private readonly Random _rng = new Random();
private const string _chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789"; //Added 1-9

private string RandomString(int size)
{
    char[] buffer = new char[size];

    for (int i = 0; i < size; i++)
    {
        buffer[i] = _chars[_rng.Next(_chars.Length)];
    }
    return new string(buffer);
}
private readonly Random\u rng=new Random();
私有常量字符串_chars=“abcdefghijklmnopqrstuvxyz123456789”//增加1-9
私有字符串随机字符串(整数大小)
{
char[]buffer=新字符[大小];
对于(int i=0;i
因此,出于脱机考虑,为每个设备生成一个并将其存储在某处可能是您唯一的选择

当设置为创建一个10位数的字符串时,该例程将生成这样的字符串,这是一个合理的随机字符串

3477KXFBDQ
ROT6GRA39O
40HTLJPFCL
5M2F44M5CH
CAVAO780NR
8XBQ44WNUA
IA02WEWOCM
EG11L4OGFO
LP2UOGKLA
H0JB0BA4NJ

KT8AN18KFA

您希望它易于检查,并且不容易“倒退”。您将看到许多关于使用哈希函数的建议,这些函数很容易单向运行,但很难反向运行,我用“把牛变成汉堡包很容易,但把汉堡包变成牛却很难”来形容。在这种情况下,设备应该知道自己的序列号,并且能够向序列号“添加”(或附加)一些秘密(通常称为“salt”),然后对其进行哈希或加密

如果您使用的是可逆加密,那么您希望在序列号中添加某种类型的“”,这样,如果有人确实了解了您的加密方案,那么他们就可以了解另一层

我解决了一个函数的例子,这个函数很容易“倒退”


而且,你可能想让你的客户更轻松,因为在手写激活码时,编码不太可能被弄乱(比如你从电子邮件中写下来,然后走到设备所在的位置,并在其中输入字母/数字)。在许多字体中,
I
1
,以及
0
O
非常相似,以至于许多编码,比如你的汽车VIN,都不使用字母
I
O
(我记得老式打字机没有数字
1
的键,因为人们希望你使用小写的
L
)。在这种情况下,
Y
4
7
可能根据某些笔迹显示相同。因此,要了解你的受众,了解他们的局限性

如何:发明一个不向用户透露的密码。然后将此密码与序列号连接起来,并对组合进行散列

你所做的任何事情都可能被一个足够专注的黑客破坏。问题不是“我能创造绝对牢不可破的安全吗?”而是“我能创造足够好的安全来抵御不熟练的黑客,让熟练的黑客付出的努力变得不值得吗?”如果你合理地期望销售1000万份你的产品,你将是一个大目标,可能会有很多黑客离开你