.NET 中的 LicenseProvider 使用 RSA 加密来保护产品许可证

发布于 2024-08-14 04:39:00 字数 584 浏览 4 评论 0原文

我正在尝试使用 Microsoft 的 LicenseProvider 找到可靠的许可方案。我的想法是通过 RSA(具有 2048 位密钥的 RSACryptoServiceProvider)方式使用异步加密。 我发现这非常简单,但我不确定该机制到底有多安全。这不是为了好玩,而是需要对美国的许多产品(我们谈论的是大约 100 个安装)进行复制保护。不需要到期日期。

现在,我使用私钥来加密许可证文件 (.lic)。在客户的计算机上,许可证管理器将在运行时根据 .lic 文件中存储的唯一 ID 检查计算机的唯一 ID。 由于该产品将具有相应的公钥,因此它可以解密该文件。 如果 ID 匹配,则许可证有效并且程序启动。

(顺便说一句,计算机 ID 是以下组合:MAC 地址 + CPU 序列号 + 硬盘序列号。因此,如果其中一项发生更改,则需要更新许可证)

就这么简单吗?在我看来,即使您可以解密 .lic 文件,您也永远无法再次对其进行加密,因为您没有所需的私钥。

现在,除了购买昂贵的第 3 方解决方案、破解和规避许可 DLL 之外,您认为使用 RSA+computerID 的想法有多安全?

(是的,我们正在研究混淆代码以使其更好)

感谢您的反馈!

I'm trying to find a solid licensing scheme using Microsoft's LicenseProvider. My thought is to use asynchronous encryption by ways of RSA (RSACryptoServiceProvider with 2048bit keys).
I found this to be pretty easy, but I am unsure how secure the mechanism really is. This isn't for fun and needs to copy-protect a number of products (we're talking ~100 installations) in the US. Expiration date is not needed.

Now, I use a private key to encrypt the license file (.lic). On the customer's computer, the license manager will check the computer's unique ID against the unique ID stored in the .lic file at runtime.
Since the product will have the corresponding public key it can decrypt the file.
If the IDs match, the license is valid and the program starts.

(BTW the computer ID is a combination of: MAC Address + CPU serial + hard drive serial. So if one of those changes, the license wil need to be renewed)

It's that simple? As I see it, even if you could decrypt the .lic file, you could never encrypt it again because you don't have the private key needed.

Now, other than buying a costly 3rd party solution, cracking and circumventing the licensing DLL, how secure do you find this idea of using RSA+computerID?

(Yes, we're looking into obfuscating the code to make this better)

Thanks for the feedback!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

深海夜未眠 2024-08-21 04:39:00

无论您是否混淆了代码,关键是您的技术并不安全并且可能会被击败。您产品的许可方案的安全程度取决于您的混淆程度。

不要使用 RSA 来加密唯一的 ID 或许可证文件,而是考虑使用 RSA 来加密具有基本核心组件或您只希望在购买的完整版本中可用的某些关键功能的模块、程序集或类库。这样,如果没有适当的许可证,完整版本的功能或应用程序的核心逻辑根本不存在,而不是您的所有辛苦工作都被完整版本“许可”软件入口点的 JMP 指令窃取。

从根本上讲,此概念最基本的实现是制作您在购买后收到的“许可证”,并且必须将公钥粘贴到程序中以解密加密的模块/程序集。然而,您不想这样做,因为一个人可以购买“许可证”,然后将其赠送给他的所有人或将其发布在他的博客上。至少,解密完整版本功能的密钥应该使用另一个密钥进行加密,并包含在软件的每个副本中。那么“许可证”将是解密真实密钥的公钥,而真实密钥对受保护的软件进行解密。通过这种方式,您可以拥有多个版本的许可证,或者如果在所有流行的连续剧网站上发布了许可证,则可以对其进行更改。

更进一步,加密许可证的“许可证”将简单地使用计算机“唯一 ID”进行散列或对称加密,该 ID 在支付处理过程中的某个时间提供给服务器。这样,只有该计算机才能生成正确的“密码短语”(如果您愿意的话),它可以恢复密钥以解密密钥以解密程序/dll/whathaveyou。

理想情况下,您可以将模块解密到受保护的内存空间中,该空间不能被其他应用程序读取,也不会分页到磁盘,然后从内存中运行,并在使用完毕后立即被覆盖。当然,这种技术并非万无一失,并且坚定的逆向工程师可能会获得解密的模块以进行重新分发,但即使要发生这种情况,有人也必须从您那里购买合法许可证。

其他想法包括将核心功能或关键数据结构存储为已编译的机器语言或中间语言,加密并存储在服务器上的某处,必须通过验证才能在每次需要执行该功能时从服务器检索该信息并解密直接进入受保护的内存,并从中执行,但这种复杂程度几乎没有必要,并且不会为所涉及的复杂程度提供大量额外的安全性。

我希望我已经给了你一些值得思考的事情。请记住,如果整个内容都被解密并可供用户复制,那么控制用户制作的副本数量就变得不可能,因此我建议在应用程序不执行时对某些组件进行加密。

Regardless if you obfuscate the code or not, the point is that you technique is not secure and can be defeated. Your product's licensing scheme will only be as secure as your obfuscation.

Rather than using RSA to encrypt a unique ID or license file, consider using RSA to encrypt a module, assembly or class library with the essential core components or certain key functionality that you only want available in the purchased full version. This way, without the proper license, the full version functions or the application's core logic is simply not there, rather than all of your hard work being stolen with a JMP instruction to the entry point of your full version, 'licensed' software.

Fundamentally, the most basic of implementations of this concept would be to make the 'license' that you receive after purchase and have to paste into the program the public key to decrypt the encrypted modules/assembly. You would not want to do this, however, as one person could purchase the 'license' and then give it away to all his or post it on his blog. At the very least, the key that decrypts the full version functionality should be encrypted using another key and included with every copy of the software. The 'license' then would be the public key that decrypts the real key that does the decryption of the protected software. This way you can have multiple versions of the license or change it up if one gets posted on all the popular serials websites.

Going further, the 'license' that encrypts the license would simply be hashed or symmetrically encrypted with the computers 'unique ID', which is provided to the server some time during the payment handling. This way only a that computer can generate the proper 'pass-phrase', if you will, that can recover the key to decrypt the key to decrypt the program/dll/whathaveyou.

Ideally you would decrypt the module into protected memory space that can not be read by other applications and is not paged to disk, then is ran from memory and is overwritten as soon as you are done with it. Sure this technique is not infallible, and a determined reverse engineer could potentially obtain a decrypted module for redistribution, but even for that to happen, someone would have had to purchased a legal license from you somewhere along the line.

Other ideas include storing core functionality or key data structures as compiled machine language or intermediate language, encrypted, and on a server somewhere, that must pass validation in order retrieve that information from the server each time that function needs to be executed, and is decrypted directly into protected memory, from which it is executed, but such level of sophistication is scarcely necessary and doesn't provide a whole lot of added security for the level of complexity involved.

I hope Ive given you some things to think about. Keep in mind, controlling the number of copies that a user makes becomes impossible if the whole thing is decrypted and available for the user to copy, so Id recommend keeping some component encrypted when the application is not executing.

沙与沫 2024-08-21 04:39:00

我有相同类型的解决方案。
然而,我只是想指出,混淆代码并不能阻止逆向工程和黑客攻击,它只是使理解逆向工程代码的工作变得更加困难。
混淆是这​​个过程中的重要一步,因为如果没有它,对代码进行逆向工程、找到安全方法并让它们返回成功的结果就相对容易(即黑客不需要花费数月时间尝试破解加密密钥)就会绕过它)。

I have the same type of solution.
However, I just wanted to point out the obsfuscating the code does not prevent revesere engineering and hacking, it just makes the job of understanding the revese engineered code much more difficult.
Obsfuscating is an important step in this process because without it, it is relatively easy to reverse engineeer the code, locate the security methods, and just make them return successful results (i.e. No need to spend months trying to crack the encryptin key, a hacker would just bypass it).

情绪 2024-08-21 04:39:00

只是为了澄清起见,(您可能已经提到过)您应该使用 [provider].SignData([params]) 对数据进行签名,并使用 [provider].VerifyData([params]) 来验证许可证。另外不要忘记从您创建的密钥对中删除私钥。

Just for clarification, (which you may have been referring to) you should Sign the data using [provider].SignData([params]) and the to validate the license use [provider].VerifyData([params]). Also not forgetting remove the private key from the key pair you have created.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文