C语言 如何在没有第三方软件的情况下生成唯一的,非顺序的串行密钥



我正在做一个项目,涉及为硬件实现编写低级C软件。我们想为我们的设备实现一个新功能,我们的用户可以在购买相关的许可密钥时解锁。

所需的实现步骤很简单。用户打电话给我们,要求我们提供功能,并向我们付款。接下来,我们给他们发一封电子邮件,让他们把产品密钥输入到硬件中,解锁该功能。

我们的硬件没有连接到互联网。因此,必须实现这样一种算法,即可以从服务器和设备内部生成这些密钥。密钥的种子可以从硬件序列号派生,这在两个位置都可用。

我需要一个简单的算法,可以采取连续的数字,并产生唯一的,16-20个字母数字字符的非顺序键。

SHA-1看起来是最好的方法。然而,我从SHA-1密钥的示例输出中看到,它们相当长(40个字符)。如果我取了40个字符的键,并且截断了除最后16个字符外的所有字符,我能得到足够的结果吗?

您可以将设备的序列号,功能名称/代码和一些秘密盐连接起来,并使用SHA1(或其他安全散列算法)对结果进行散列。设备将给定的哈希值与为每个特性生成的哈希值进行比较,如果找到匹配,则启用该特性。

顺便说一下,为了减少字符计数,我建议在哈希传递后使用base64作为编码。

SHA-1看起来是最好的方法。然而,我从SHA-1密钥的示例输出中看到,它们相当长(40个字符)。如果我取40个字符的结果,并且截断除最后16个字符外的所有字符,我会获得足够的结果吗?

一般来说,截断哈希不是一个好主意,它们的设计目的是利用输出的所有长度来提供良好的安全性和抗碰撞性。但是,您可以使用base64而不是十六进制字符来减少字符数,它将从40个字符减少到27个字符。

Hex:    a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
Base64: qUqP5cyxm6YcTAhz05Hph5gvu9M

——编辑——

实际上,@Nick Johnson以令人信服的论据声称哈希可以被截断而不会产生大的安全隐患(显然,每丢失一个比特就会增加两次碰撞的机会)。

您还应该使用HMAC,而不是简单地在散列中添加或附加密钥。每维基百科:

HMAC规范的设计是由针对将键与散列组合在一起的更琐碎的机制的攻击函数。例如,可以假设与HMAC具有相同的安全性提供可以通过MAC = H(key∥message)来实现。然而,这方法有一个严重的缺陷:对于大多数散列函数,它是很容易在不知道密钥的情况下向消息追加数据并获得另一个有效的MAC。另一种选择,使用MAC =附加密钥H(消息∥密钥),遭受攻击者谁都可以的问题在(无键)哈希函数中找到一个冲突MAC:使用MAC = H(key∥message∥key)比较好,但是各种各样安全论文指出了这种方法的漏洞,即使使用了两个不同的键

有关此截断和长度截断的安全含义的详细信息,请参见RFC2104的第5节和第6节。

一种选择是使用Matteo描述的散列。

另一种是使用分组密码(例如AES)。只需随机选择一个nonce,并使用您的序列号作为计数器在计数器模式下调用密码。

当然,这将使键可逆,这可能是也可能不是一个理想的属性。

您可以使用Xorshift随机数生成器生成唯一的64位密钥,然后使用您想要的任何方案对该密钥进行编码。如果使用base-64,则密钥长度为11个字符。如果使用十六进制编码,则密钥长度为16个字符。

Xorshift RNG基本上只是一个位混频器,有些版本有2^64的保证周期,这意味着它保证为每个输入生成一个唯一的值。

另一种选择是使用线性反馈移位寄存器,它也将为每个不同的输入生成一个唯一的数字。

最新更新