如何在没有第三方软件的情况下生成独特的非顺序串行密钥?

时间:2021-03-07 18:55:49

I'm working on a project that involves writing low-level C software for a hardware implementation. We are wanting to implement a new feature for our devices that our users can unlock when they purchase an associated license key.

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

The desired implementation steps are simple. The user calls us up, they request the feature and sends us a payment. Next, we email them a product key which they input into their hardware to unlock the feature.

期望的实现步骤很简单。用户给我们打电话,他们请求该功能并向我们发送付款。接下来,我们通过电子邮件向他们发送产品密钥,然后将其输入到硬件中以解锁该功能

Our hardware is not connected to the internet. Therefore, an algorithm must be implemented in such a way that these keys can be generated from both the server and from within the device. Seeds for the keys can be derived from the hardware serial number, which is available in both locations.

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

I need a simple algorithm that can take sequential numbers and generate unique, non-sequential keys of 16-20 alphanumeric characters.

我需要一个简单的算法,它可以采用序列号并生成16-20个字母数字字符的唯一,非连续键。

UPDATE

UPDATE

SHA-1 looks to be the best way to go. However, what I am seeing from sample output of SHA-1 keys is that they are pretty long (40 chars). Would I obtain sufficient results if I took the 40 char key and, say, truncated all but the last 16 characters?

SHA-1看起来是最好的方式。但是,我从SHA-1键的示例输出中看到的是它们很长(40个字符)。如果我使用40个字符键,然后截断除了最后16个字符以外的所有字符,我会获得足够的结果吗?

3 个解决方案

#1


13  

You could just concatenate the serial number of the device, the feature name/code and some secret salt and hash the result with SHA1 (or another secure hashing algorithm). The device compares the given hash to the hash generated for each feature, and if it finds a match it enables the feature.

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

By the way, to keep the character count down I'd suggest to use base64 as encoding after the hashing pass.

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

SHA-1 looks to be the best way to go. However, what I am seeing from sample output of SHA-1 keys is that they are pretty long (40 chars). Would I obtain sufficient results if I took the 40 char result and, say, truncated all but the last 16 characters?

SHA-1看起来是最好的方式。但是,我从SHA-1键的示例输出中看到的是它们很长(40个字符)。如果我采用40个字符的结果,并且比如删除除了最后16个字符以外的所有字符,我会获得足够的结果吗?

Generally it's not a good idea to truncate hashes, they are designed to exploit all the length of the output to provide good security and resistance to collisions. Still, you could cut down the character count using base64 instead of hexadecimal characters, it would go from 40 characters to 27.

通常,截断哈希值并不是一个好主意,它们旨在利用输出的所有长度来提供良好的安全性和抵抗冲突。不过,你可以使用base64而不是十六进制字符来减少字符数,它会从40个字符变为27个字符。

Hex:    a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
Base64: qUqP5cyxm6YcTAhz05Hph5gvu9M

---edit---

- -编辑 - -

Actually, @Nick Johnson claims with convincing arguments that hashes can be truncated without big security implications (obviously increasing chances of collisions of two times for each bit you are dropping).

实际上,@尼克约翰逊用令人信服的论证声称哈希可以被截断而没有大的安全隐患(显然,你丢弃的每一个比特的碰撞机会增加两倍)。

You should also use an HMAC instead of naively prepending or appending the key to the hash. Per Wikipedia:

您还应该使用HMAC而不是天真地预先添加或将密钥附加到哈希。每个*:

The design of the HMAC specification was motivated by the existence of attacks on more trivial mechanisms for combining a key with a hash function. For example, one might assume the same security that HMAC provides could be achieved with MAC = H(key ∥ message). However, this method suffers from a serious flaw: with most hash functions, it is easy to append data to the message without knowing the key and obtain another valid MAC. The alternative, appending the key using MAC = H(message ∥ key), suffers from the problem that an attacker who can find a collision in the (unkeyed) hash function has a collision in the MAC. Using MAC = H(key ∥ message ∥ key) is better, however various security papers have suggested vulnerabilities with this approach, even when two different keys are used.

HMAC规范的设计的动机是存在对用于将密钥与散列函数组合的更简单机制的攻击。例如,可以假设使用MAC = H(密钥∥消息)可以实现HMAC提供的相同安全性。但是,这种方法存在严重的缺陷:对于大多数散列函数,很容易在不知道密钥的情况下将数据附加到消息并获得另一个有效的MAC。使用MAC = H(消息∥密钥)附加密钥的替代方案存在以下问题:能够在(未密钥)散列函数中发现冲突的攻击者在MAC中发生冲突。使用MAC = H(密钥∥消息∥密钥)更好,但是各种安全性文件都提出了这种方法的漏洞,即使使用了两个不同的密钥。

For more details on the security implications of both this and length truncation, see sections 5 and 6 of RFC2104.

有关此截断和长度截断的安全隐患的更多详细信息,请参阅RFC2104的第5节和第6节。

#2


2  

One option is to use a hash as Matteo describes.

一种选择是使用Matteo描述的哈希。

Another is to use a block cipher (e.g. AES). Just pick a random nonce and invoke the cipher in counter mode using your serial numbers as the counter.

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

Of course, this will make the keys invertible, which may or may not be a desirable property.

当然,这将使钥匙可翻转,这可能是也可能不是理想的属性。

#3


0  

You can use an Xorshift random number generator to generate a unique 64-bit key, and then encode that key using whatever scheme you want. If you use base-64, the key is 11 characters long. If you use hex encoding, the key would be 16 characters long.

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

The Xorshift RNG is basically just a bit mixer, and there are versions that have a guaranteed period of 2^64, meaning that it's guaranteed to generate a unique value for every input.

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

The other option is to use a linear feedback shift register, which also will generate a unique number for each different input.

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

#1


13  

You could just concatenate the serial number of the device, the feature name/code and some secret salt and hash the result with SHA1 (or another secure hashing algorithm). The device compares the given hash to the hash generated for each feature, and if it finds a match it enables the feature.

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

By the way, to keep the character count down I'd suggest to use base64 as encoding after the hashing pass.

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

SHA-1 looks to be the best way to go. However, what I am seeing from sample output of SHA-1 keys is that they are pretty long (40 chars). Would I obtain sufficient results if I took the 40 char result and, say, truncated all but the last 16 characters?

SHA-1看起来是最好的方式。但是,我从SHA-1键的示例输出中看到的是它们很长(40个字符)。如果我采用40个字符的结果,并且比如删除除了最后16个字符以外的所有字符,我会获得足够的结果吗?

Generally it's not a good idea to truncate hashes, they are designed to exploit all the length of the output to provide good security and resistance to collisions. Still, you could cut down the character count using base64 instead of hexadecimal characters, it would go from 40 characters to 27.

通常,截断哈希值并不是一个好主意,它们旨在利用输出的所有长度来提供良好的安全性和抵抗冲突。不过,你可以使用base64而不是十六进制字符来减少字符数,它会从40个字符变为27个字符。

Hex:    a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
Base64: qUqP5cyxm6YcTAhz05Hph5gvu9M

---edit---

- -编辑 - -

Actually, @Nick Johnson claims with convincing arguments that hashes can be truncated without big security implications (obviously increasing chances of collisions of two times for each bit you are dropping).

实际上,@尼克约翰逊用令人信服的论证声称哈希可以被截断而没有大的安全隐患(显然,你丢弃的每一个比特的碰撞机会增加两倍)。

You should also use an HMAC instead of naively prepending or appending the key to the hash. Per Wikipedia:

您还应该使用HMAC而不是天真地预先添加或将密钥附加到哈希。每个*:

The design of the HMAC specification was motivated by the existence of attacks on more trivial mechanisms for combining a key with a hash function. For example, one might assume the same security that HMAC provides could be achieved with MAC = H(key ∥ message). However, this method suffers from a serious flaw: with most hash functions, it is easy to append data to the message without knowing the key and obtain another valid MAC. The alternative, appending the key using MAC = H(message ∥ key), suffers from the problem that an attacker who can find a collision in the (unkeyed) hash function has a collision in the MAC. Using MAC = H(key ∥ message ∥ key) is better, however various security papers have suggested vulnerabilities with this approach, even when two different keys are used.

HMAC规范的设计的动机是存在对用于将密钥与散列函数组合的更简单机制的攻击。例如,可以假设使用MAC = H(密钥∥消息)可以实现HMAC提供的相同安全性。但是,这种方法存在严重的缺陷:对于大多数散列函数,很容易在不知道密钥的情况下将数据附加到消息并获得另一个有效的MAC。使用MAC = H(消息∥密钥)附加密钥的替代方案存在以下问题:能够在(未密钥)散列函数中发现冲突的攻击者在MAC中发生冲突。使用MAC = H(密钥∥消息∥密钥)更好,但是各种安全性文件都提出了这种方法的漏洞,即使使用了两个不同的密钥。

For more details on the security implications of both this and length truncation, see sections 5 and 6 of RFC2104.

有关此截断和长度截断的安全隐患的更多详细信息,请参阅RFC2104的第5节和第6节。

#2


2  

One option is to use a hash as Matteo describes.

一种选择是使用Matteo描述的哈希。

Another is to use a block cipher (e.g. AES). Just pick a random nonce and invoke the cipher in counter mode using your serial numbers as the counter.

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

Of course, this will make the keys invertible, which may or may not be a desirable property.

当然,这将使钥匙可翻转,这可能是也可能不是理想的属性。

#3


0  

You can use an Xorshift random number generator to generate a unique 64-bit key, and then encode that key using whatever scheme you want. If you use base-64, the key is 11 characters long. If you use hex encoding, the key would be 16 characters long.

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

The Xorshift RNG is basically just a bit mixer, and there are versions that have a guaranteed period of 2^64, meaning that it's guaranteed to generate a unique value for every input.

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

The other option is to use a linear feedback shift register, which also will generate a unique number for each different input.

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