我目前正在开发一个产品(用c#开发的),可以免费下载和安装,但版本非常有限。要获得所有功能,用户必须支付许可费并获得密钥。然后,该密钥将被输入应用程序以“解锁”完整版本。

像这样使用许可密钥是很常见的,我想知道:

这个问题通常是怎么解决的? 如何生成密钥以及应用程序如何验证密钥? 我怎样才能避免一个密钥被发布在互联网上,并被其他没有支付许可证的人使用(一个基本上不是“他们的”密钥)。

我想我还应该以某种方式将密钥绑定到应用程序的版本,这样就有可能在功能版本中对新密钥收费。

在这种情况下,还有什么需要考虑的吗?


当前回答

我知道这是一个老问题,但我在为我的一个应用程序重新编写许可流程时引用了这个问题。

在阅读了大量的意见并依靠过去的许可代码经验后,我想出了这个过程。

public static class LicenseGenerator
{
    private static string validChars = "ACEFHJKMNPRSTUVWXYZ234579";
    private static Random rnd = new Random(Guid.NewGuid().GetHashCode());

    /// <summary>
    /// Generate a license code
    /// </summary>
    /// <param name="length">length of each phrase</param>
    /// <param name="number">number of phrases separated by a '-'</param>
    /// <returns></returns>
    public static string GetNewCode(int length, int number)
    {
        string license = string.Empty;

        for (int numberOfPhrases = 0; numberOfPhrases < number; numberOfPhrases++)
        {
            license += getPhrase(length);
            if (numberOfPhrases < number)
                license += "-";
        }

        return license.TrimEnd('-');
    }

    /// <summary>
    /// generate a phrase
    /// </summary>
    /// <param name="length">length of phrase</param>
    /// <returns></returns>
    private static string getPhrase(int length)
    { 
        string phrase = string.Empty;

        for (int loop = 0; loop < length; loop++)
        {
            phrase += validChars[rnd.Next(validChars.Length)];
        }

        return phrase;
    }
}

你真的不想提供一个有相似字母的代码;当最终用户输入时,它会造成混乱。像6和G, B和8,L, I和1。当然,如果你真的想要它们,你可以随时把它们加回来……上面的代码将使用“validChars”中的字符生成类似xxxx-xxxx-xxxx-xxxx的许可证。调用GetNewCode(4,4)将返回与上面类似的代码。

我使用Azure函数注册然后验证代码。当我的应用程序注册代码时,它会生成一个加密散列,其中包含安装、设备和/或用户独有的内容。它被提供给注册函数,并与密钥一起存储在Azure的DB中。

验证重新生成密钥,并向其提供许可代码、IP地址(在我的例子中,IP地址不会改变,如果改变了,那么无论如何都需要更新)和重新生成的散列,然后Azure函数在应用程序获得许可时返回。我确实在他们的服务器上存储了一个“临时”密钥,允许应用运行一段时间而不返回。

当然,我的应用程序必须在网络上,它的工作无论如何。

因此,最终结果是一个供最终用户输入的简单密钥,以及在后端管理许可证的简单流程。如果需要,我还可以使许可证无效。

其他回答

我坚信,只有基于公钥密码学的许可系统才是正确的方法,因为您不必将许可证生成所需的基本信息包含到源代码中。

在过去,我曾多次使用Treek的授权库,因为它满足了这一要求,并提供了非常好的价格。它对终端用户和自身使用相同的许可证保护,直到现在还没有人破解它。你也可以在网站上找到避免盗版和破解的好建议。

在生成密钥时,不要忘记将版本和构建号连接到计算散列的字符串上。这样就不会有一把钥匙能打开你释放的所有东西。

当你在astalavista.box.sk中找到一些密钥或补丁后,你就会知道你成功地让某些东西变得流行,以至于有人费心去破解。喜乐!

简单的答案-无论你使用什么方案都可以被破解。

不要用一个旨在防止黑客的系统来惩罚诚实的客户,因为黑客无论如何都会破解它。

一个简单的散列代码绑定到他们的电子邮件或类似的可能就足够了。当人们需要重新安装或更新硬件时,基于硬件的id总是会成为一个问题。

关于这个问题的好帖子: http://discuss.joelonsoftware.com/default.asp?biz.5.82298.34

我知道这是一个老问题,但我在为我的一个应用程序重新编写许可流程时引用了这个问题。

在阅读了大量的意见并依靠过去的许可代码经验后,我想出了这个过程。

public static class LicenseGenerator
{
    private static string validChars = "ACEFHJKMNPRSTUVWXYZ234579";
    private static Random rnd = new Random(Guid.NewGuid().GetHashCode());

    /// <summary>
    /// Generate a license code
    /// </summary>
    /// <param name="length">length of each phrase</param>
    /// <param name="number">number of phrases separated by a '-'</param>
    /// <returns></returns>
    public static string GetNewCode(int length, int number)
    {
        string license = string.Empty;

        for (int numberOfPhrases = 0; numberOfPhrases < number; numberOfPhrases++)
        {
            license += getPhrase(length);
            if (numberOfPhrases < number)
                license += "-";
        }

        return license.TrimEnd('-');
    }

    /// <summary>
    /// generate a phrase
    /// </summary>
    /// <param name="length">length of phrase</param>
    /// <returns></returns>
    private static string getPhrase(int length)
    { 
        string phrase = string.Empty;

        for (int loop = 0; loop < length; loop++)
        {
            phrase += validChars[rnd.Next(validChars.Length)];
        }

        return phrase;
    }
}

你真的不想提供一个有相似字母的代码;当最终用户输入时,它会造成混乱。像6和G, B和8,L, I和1。当然,如果你真的想要它们,你可以随时把它们加回来……上面的代码将使用“validChars”中的字符生成类似xxxx-xxxx-xxxx-xxxx的许可证。调用GetNewCode(4,4)将返回与上面类似的代码。

我使用Azure函数注册然后验证代码。当我的应用程序注册代码时,它会生成一个加密散列,其中包含安装、设备和/或用户独有的内容。它被提供给注册函数,并与密钥一起存储在Azure的DB中。

验证重新生成密钥,并向其提供许可代码、IP地址(在我的例子中,IP地址不会改变,如果改变了,那么无论如何都需要更新)和重新生成的散列,然后Azure函数在应用程序获得许可时返回。我确实在他们的服务器上存储了一个“临时”密钥,允许应用运行一段时间而不返回。

当然,我的应用程序必须在网络上,它的工作无论如何。

因此,最终结果是一个供最终用户输入的简单密钥,以及在后端管理许可证的简单流程。如果需要,我还可以使许可证无效。

你可以使用免费的第三方解决方案来解决这个问题,比如Quantum-Key。Net它是免费的,通过paypal为你创建的网络销售页面处理支付,通过电子邮件发放钥匙,并将钥匙锁定到特定的计算机以防止盗版。

你还应该注意混淆/加密你的代码,或者它可以很容易地使用De4dot和. netreflector等软件进行逆向工程。ConfuserEx是一个很好的免费代码混淆器,它使用起来快速简单,比昂贵的替代品更有效。

你应该通过De4Dot和. netreflector运行你完成的软件来逆向工程它,看看黑客会看到什么,如果他们做同样的事情,并确保你没有留下任何重要的代码暴露或未伪装。

你的软件仍然是可以被破解的,但对于那些偶然的破解者来说,这可能足以让他们望而却步,这些简单的步骤也可以防止你的代码被提取和重用。

https://quantum-key.net

如何使用ConfuserEx?

https://github.com/0xd4d/de4dot

https://www.red-gate.com/dynamic/products/dotnet-development/reflector/download