穷人序列号生成方案

Poor man serial number generation scheme

我想得到一些简单的方案/算法,用于根据一些唯一的硬件 ID(cpu ID 或以太网 mac 地址或硬盘序列号)生成序列号。

我希望方案只在一个方向上工作 - 因此客户端 machine 上的应用程序可以验证序列号但不能生成序列号。 (所以破解起来不会简单)

现在很可能你们中的大多数人会推荐某种 RSA public / 私钥对加密,它可以足够可靠地工作 - 客户端没有私钥,所以他不能 "generate"序列号。

但 RSA 签名的主要问题是它太大了 - 它的签名大小为 128 或 256 字节,具体取决于 RSA 密钥大小 (RSA signature size?)

好的,现在您可能会说这种保护不足以抵御暴力破解 - 您只需尝试所有组合即可确定正确的序列号。

但我要说的是,通常您需要聘请 "expensive" 黑客或黑客团队来创建此类暴力破解应用程序。

此外,我认为可以为下一版本的应用程序更改序列号生成算法,或者使用多轮传递来显着减慢暴力破解。

作为基础,我更愿意使用纯 C 或 C++(不是 C#),最好是 Windows / wincrypt.h 或任何现有的纯 C 源代码(最好不是庞大的第 3 方库).

是否可以创建 RSA public/私钥对以便签名大小为 32 个字符长?

您正在寻找加密哈希函数。一个适合您所需的 32 个字符的好例子是 md5.

您可能想查看 ECDSA

ECDSA 是一种类似于 RSA 的 public 密钥算法,但其密钥和签名大小比 RSA 更短,可提供相同级别的有效安全性。 ECDSA 基于椭圆曲线密码学。 RSA 中使用的整数分解问题和 ECDSA 中使用的椭圆曲线问题都归结为离散对数问题,这被认为是难以解决的。

例如,对于与 1024 位 RSA 相同的安全级别,估计具有大约 80 位的安全性,您可以使用 160 位的 ECDSA 密钥,它会产生 320 位的签名。您可以将 320 位签名编码为 54 个字符的字符串,或将 ascii85 编码为 50 个字符的字符串。

或者,如果您想使用 base64 编码保留 32 个字符,最多可容纳 192 位数据,则​​可以使用密钥大小为 96 位的 ECDSA。 96 位 ECDSA 的有效强度是 48 位,通常不足以进行适当的加密,但在您的情况下,攻击者可能仍然更容易对程序进行逆向工程以删除您的许可证密钥检查,而不是尝试生成伪造密钥。

我已经决定post我自己的解决方案,它使用现在在这个论坛上提出的 ECDSA 私有/public 密钥对,并且包括我所了解的双向加密算法的使用在这里问过: Poor man serial number generation scheme, part 2

代码可能仍然包含一些错误,但我已尽我所能并测试我能做的一切。

它还使用托管代码部分和 C# 代码来测试 C++ 代码,但根据您的实现,您可能希望完全放弃托管部分。

因为这里的答案大小有限,我不得不将我的代码放在外部 url - 这样答案的大小就足够小了。

这是我的代码片段:

第三个代码不完整 - 它只是如何编码的演示代码。如果你不使用C#,那么上层可能是别的东西。

对于 EDSCA 签名算法,我使用了 https://github.com/esxgx/easy-ecc,几乎没有修复 - 以缩短签名的大小:

/* Curve selection options. */
#define secp128r1 16

#ifndef ECC_CURVE
    #define ECC_CURVE secp128r1
#endif
  • 尽可能小的签名大小。

现在,当您开始查看代码时 - 您会注意到 public 和私钥对未初始化 - 因为它们与我的产品紧密绑定。但是让我 post 一些演示密钥(我已经使用当前代码来初始化它们)

unsigned char publicKey[] = {
    0x03, 0x7A, 0x0E, 0xE4, 0x2C, 0xC1, 0x29, 0x1D, 0x22, 0xCF, 0x6F, 0xCE, 0x03, 0x5F, 0xBF, 0x31, 0xDD, 
};
unsigned char encryptedPrivateKey[] = {
    0x9E, 0x8C, 0x4C, 0x8F, 0x02, 0x1D, 0x7E, 0x34, 0xA0, 0xDB, 0xBC, 0x45, 0xD8, 0x1A, 0x57, 0x7A, 
};

因此使用当前 public / 私钥对 - 对于硬件 ID 000000000000(来自网卡 mac 地址) - 以下序列密钥有效:

pc000000000000-NnE84PSfl8nFxmhpHn+gvNFwZNkwuEFKAzu/yEmDohc=

现在包含签名部分 ("pc000000000000") 和签名本身 ("NnE84PSfl8nFxmhpHn+gvNFwZNkwuEFKAzu/yEmDohc=")。

现在最好的部分是您现在拥有我的解决方案的完整源代码,包括 public 和私钥。缺少的是我用来加密管理员私钥的密码——但没有它你就无法生成序列号。我现在挑战黑客破解这个解决方案 - 为我的软件创建序列密钥生成器。相当有趣的困境——你有完整的源代码,但它对你毫无用处。 :-)

我觉得破解软件还是可以的(Asm的跳转短,不用操作),但这是总能做到的事情

目标是通过引入简单、小而漂亮的串行密钥生成解决方案来让黑客的生活更难一些——可以简单地从一种产品复制粘贴到另一种产品的解决方案。