2

我正在寻找有关创建系统的指导,该系统将允许我锁定我的程序并将它们置于试用模式。我想要指导的部分是创建/检查密钥的算法,你们对它应该是什么样子有什么建议吗?我正在使用 c#。

4

3 回答 3

0

您忘记了有一些工具,如dotPeekJustDecompile.NET Reflector,它们可以轻松地将您的应用程序反汇编为源代码。您的保护很容易被移除。SO上有很多类似的线程,处理混淆,序列号等。这里有两个关于代码混淆的链接。

https://stackoverflow.com/questions/1988451/net-obfuscation

.NET 世界中混淆的替代方案

老实说,您将花费大量时间在保护上,最终可能会浪费时间。这是不幸的,但这是现实。

于 2012-05-03T13:11:13.793 回答
0

那么最好的方法是实现你自己的真正硬编码的套接字协议,这样黑客就无法解码它,你应该不断地改变它。另外要检查许可证,您应该只联系您的套接字服务器,而套接字服务器可以简单地联系数据库并检查密钥是否有效。

这就是我会做的,它可以很容易地实现

于 2012-05-03T12:59:53.547 回答
0

转自:生成产品激活序列号

基本上 - 一旦软件在其他人的计算机上,他们就有能力随心所欲地修改软件,您无法阻止他们,除非采取法律行动,证明反汇编并执行法律处罚。

如果您真的想保护功能,您将保持安全功能在线,并通过 Web 服务调用它。这样他们就被迫付费使用您的 Web 服务。但是,如果您想找到一种生成串行密钥的方法。下面是我写的一篇文章,描述了一种生成“困难”串行密钥的方法,它需要很长时间才能制作,但需要少量时间来验证。使用这种算法,您可以在数据库中预先生成序列密钥,然后将它们分发给客户。唯一的问题是再一次 - 有人可能会反汇编您的应用程序并删除代码的许可部分。我会改为让用户必须拥有有效的序列号才能下载软件并下载所有更新。这将激励成为合法和合法的客户。因此,如何使用这些序列的示例如下:您使用以下代码生成 100 个序列组合。保存它们,然后将它们出售给客户。给他们序列号,产品密钥(数字)。

然后在激活时,他们将其输入您的网站,然后网站将软件发送给他们。

您的网站获取序列号,即他们输入的产品密钥,并将其与软件的密码短语相结合。(下例中的 Alpha)如果 3 个部分联合在一起生成了适当强度/难度的 SHA256 哈希,那么它将认为它是成功注册。此外,您可以检查用户数据库以查看该序列是否与相关客户匹配。如果您想获得真正的安全,您可以创建一个启动器应用程序,为您的产品下载二进制文件,并在成功验证序列密钥后通过 Assembly.Load 加载它们。无论如何-重新发布现在开始。

转发:

使用串行密钥,您需要考虑一些事情。

我在狩猎过程中看到了指向使用简单 Guid.NewGuid(); 的链接。方法,然后对字符串进行一些转换以制作自定义样式的序列键。这很容易做到,但产品所有者有责任跟踪数据库中的序列号,最终有人可能会随机找到通过使用 Guid.NewGuid() 工作的序列号;他们自己。如果地球上的每个人都同时开始生成 Guid,那么碰撞的可能性就变得很大。

有一种解决方案可以通过在 Guid.NewGuid() 之上使用更复杂的算法来降低碰撞事件的可能性;

为此,我倾向于使用:

  1. Guid.NewGuid(); (仅前 16 个字符,减去 -(连字符)
  2. 一个不断增加或变化的值。(随机数)(一个 int 可以工作:i++ 等)
  3. 您将在网络中保持私密和安全的秘密盐。
  4. 一个困难因素:从比特币中借用这个原理。

好的,让我们想象一下我正在从 guid 中获取前 16 位数字。然后我将它与 Nonce 和秘密盐结合起来,然后使用 SHA256 从值中派生散列。然后我可以使用难度系数来确定哈希是否以我想要的 0 或其他字符的数量开头。

例如:如果哈希前面有六个 0,那么我将所有数据都保存下来,因为我刚刚找到了一个相当安全的串行密钥。

当我的意思是安全时,我的意思是我找到了一个序列,当它与产品密钥(Nonce)结合使用,然后与秘密 Salt 一起使用时,它会产生一个符合我的生产标准的哈希。

下面是一些示例代码 - 做得非常粗糙,因为我很无聊。

这个想法是您的应用程序可以将产品密钥和序列号发送到激活服务器。服务器知道秘密盐。然后它返回 true 或 false 以确定生成的哈希是否满足安全要求。如果不是:序列号无效,或者对提供的密钥无效。如果它确实有所需的 0:它是一个有效的序列。

    Guid theGuid;
    string Hash = "";
    int iAccess = 0;
    string PrivateSalt = "Alpha";
    string SourceString = "";
    string guidString;
    while (true)
    {
        theGuid = Guid.NewGuid();
        guidString = theGuid.ToString().Replace("-", "").Substring(0,16);
        SourceString = guidString + "|" + iAccess.ToString() + "|" + PrivateSalt;
        byte[] data = Encoding.Default.GetBytes(SourceString);
        Hash = Crypto.GenerateSHA256(data);
        if (Hash.StartsWith(GetDiff()))
        {
            break;
        }

        iAccess++;
    }
    Console.WriteLine(SourceString+" Gives hash "+Hash);
    string s1, s2, s3, s4;
    s1 = guidString.Substring(0, 4);
    s2 = guidString.Substring(4, 4);
    s3 = guidString.Substring(8, 4);
    s4 = guidString.Substring(12, 4);
    string serial = s1 + "-" + s2 + "-" + s3 + "-" + s4;

    Console.WriteLine(serial + " :" + SourceString + " Gives hash " + Hash);

GetDiff() 基本上只是一个字符串:“000000”;

此方法的示例输出如下所示:

d9c9-f6f0-45be-427a :d9c9f6f045be427a|15135|Alpha Gives hash    000000f718f69c8389d496e01d1e992946fe1b8cf72bc4200a7a2b800b40aa0a
fe49-70b9-08d8-40df :fe4970b908d840df|9096414|Alpha Gives hash  000000e29cfccfb54d1e7edc816feb084f1a2cd11a20c3132a965f9048fc9bf4
7f58-0636-c853-4f0a :7f580636c8534f0a|12297217|Alpha Gives hash 0000007bb44f39a964bbe985885451c3dc0e037fcd12951261404e48819bf89b
6f65-82d3-d95b-4882 :6f6582d3d95b4882|15064854|Alpha Gives hash 000000f1a3bed79e441108cfd26d8733d3fc10f5cd66d234ed35fe2b769663a3
edee-b8b7-9f6f-40ab :edeeb8b79f6f40ab|17782415|Alpha Gives hash 000000b70b96e7b008a96a860efc572fe868154ae81e67b9397249a51f2db71c
0948-4bb3-7de4-4054 :09484bb37de44054|21105690|Alpha Gives hash 000000ec7317eccd5fd9bb701759a2b0e77d37099347d9d665f4b492a69ca3ec
bbf5-5119-bf4e-463c :bbf55119bf4e463c|21715642|Alpha Gives hash 000000a134c886d01606da83cd5e8f672fddb6aa061968e9f08202c781514b16
80f6-c9c5-0ddf-436d :80f6c9c50ddf436d|26450310|Alpha Gives hash 00000092305b2956381c23dacba5b8ff9a37ab994148b37677732dc2a0650386
0a4f-143b-b5f5-48ca :0a4f143bb5f548ca|33691865|Alpha Gives hash 00000054ecdae57c6ec686b6084faf68ae49a78f7c07bbe8e51357d76de63870

您可以通过在前缀中添加更多的 0 来增加难度。这意味着查找串行组合将花费更长的时间,但也使其更加安全。

显然,您会将这些数据组合存储在某个地方,因此在激活期间,您可以比较序列号和产品密钥(Nonce)。

在我的示例中:我正在使用序列密钥(16 位)、递增 int 和单词 Alpha 来表示秘密盐。

这使得生成串行密钥很慢且 CPU 密集,但验证它们的速度非常快。

IsSerialValid("edee-b8b7-9f6f-40ab", 17782415);

public bool IsSerialValid(string serialCode, int ProductCode)
        {
            string SourceString = serialCode.Replace("-", "") + "|" + ProductCode.ToString() + "|" + "Alpha";
            byte[] data = Encoding.Default.GetBytes(SourceString);
            string Hash = Crypto.GenerateSHA256(data);
            if (Hash.StartsWith(GetDiff()))
            {
                return true;
            }
            return false;
        }

秘密 Salt 可能是一个代码短语,它映射到您可能正在开发的不同产品。这允许您跨多个产品线重复使用产品密钥 (Nonce) 值。

于 2016-02-01T13:31:35.403 回答