2

我正在尝试为我的 C# 2.0 桌面应用程序创建一个注册码,这是一个按使用付费的应用程序。注册码必须在其中隐藏一个 int 值(int 值代表应用程序的使用次数)。

为了从我的机器生成代码,我有一个单独的应用程序,它使用名称、随机数和使用次数作为输入。例如:

Name:  BOBSMITH  
Random number:  51728  
Number of Uses: 50  
Concatenated String: BOBSMITH_51728_50

如果我对连接字符串(例如 MD5 哈希)进行哈希处理,我会得到一个 32 十六进制字符串(我将其称为 Reg 代码),类似于: ABCD 1234 EFGH 5678 IJKL 9012 MNOP 3456

现在,在我的用户方面,当他们注册应用程序时,我需要验证注册代码并从注册代码/名称/随机数中确定使用次数。所以用户将输入这些值:

Name: BOBSMITH  
Random Number: 51728  
Reg Code: ABCD 1234 EFGH 5678 IJKL 9012 MNOP 3456 

我的问题:我的应用程序如何确定(仅基于名称、随机数和注册码):

  • 注册码是否正确
  • 我的机器最初给出的使用次数

我想到的一个简单想法是仅基于名称和随机数(我们称之为代码 A)生成一个哈希,然后将使用次数添加到此哈希(代码 B)中。例如:

Code A: ABCD 1234 EFGH 5678 IJKL 9012 MNOP **1184**  
Code B: ABCD 1234 EFGH 5678 IJKL 9012 MNOP **11B6**

如果我们从代码 B 中减去代码 A,我们得到 50。因此,我的用户将输入这些值:

Name:BOBSMITH  
Random Number: 51728  
Reg Code: ABCD 1234 EFGH 5678 IJKL 9012 MNOP 11B6  (Code B)  

为了验证 Reg 代码和使用次数(从用户端),我的应用程序将采用 Name & Random Number 的哈希值,这将给出与 Code A 相同的值。然后我将从 Reg Code 中减去 Code A用户输入并看到差异是 50。因此,我知道给用户 50 次使用。然而,这个解决方案似乎太不安全了。我会很感激任何人的建议。

4

3 回答 3

4

TL;DR 版本:这是不可能的。“按使用付费”和“桌面应用程序”不能混用。


隐藏数字实际上是目标,还是您假设隐藏它有助于防止篡改?(您是否试图不向消费者展示他们已经支付了多少次使用费用?听起来不诚实。)您可以使用消息验证码来验证该值没有被篡改,即使该数字存储在显而易见的地方,因为更改将使 MAC 无效。

但是,这仍然不能解决您的问题。如果用户可以篡改已使用次数的计数器,则对保护已购买的使用次数没有任何好处。在最简单的攻击中,用户只需在第二台计算机上输入相同的注册码,就可以使使用次数翻倍。并且这个计数器必须由用户计算机上运行的软件增加,因此他必须拥有更新它所需的所有信息。

即使您将计数器存储在您控制下的某个安全中央服务器上(这也消除了保护允许使用计数的问题),您仍然无法阻止用户修补调用 home 的软件部分。您唯一能做的就是将软件托管在云中,这样您就可以在没有用户合作的情况下计算使用次数。

请参阅#1 软件许可法

于 2012-12-05T20:46:36.470 回答
0

安全哈希的定义不允许任何取回数字的可能性。

但这并不意味着您可以散列其他所有内容,然后以另一种方式隐藏散列码中的数字。您在哈希末尾添加一个数字的示例可以工作,但是如果您这样做,我还建议您还从结果值计算校验和并将其附加到代码中以使篡改变得困难。

于 2012-12-05T20:30:40.587 回答
0

散列只是单向的,所以你将无法取回你散列的任何东西。加密是双向的,因此您将能够取回您加密的任何内容。

为防止有人更改加密号码,您还需要进行身份验证。要么使用 AES-GCM(包括身份验证),要么使用 AES-CTR 或 AES-CBC(不包括身份验证)与 HMAC-SHA-256 一起进行身份验证。

计算机安全并不容易。很多问题已经解决了,但解决方案并不总是那么简单。显然,微小的错误可能会导致重大的安全漏洞。

于 2012-12-13T23:52:49.407 回答