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

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

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

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

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


当前回答

除了已经说过的....

由于中间语言的问题,. net应用程序的任何使用本质上都是容易被破坏的。对. net代码进行简单的反汇编就可以向任何人打开您的产品。他们可以很容易地绕过你的授权代码。

你甚至不能再使用硬件值来创建键了。虚拟机现在允许人们创建一个“许可”机器的映像,并在他们选择的任何平台上运行它。

如果软件价格昂贵,还有其他解决方案。如果不是,那就给普通黑客制造足够的难度。接受这个事实,即最终会有未授权的副本出现。

如果你的产品很复杂,固有的支持问题将为你创造一些保护。

其他回答

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

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

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函数在应用程序获得许可时返回。我确实在他们的服务器上存储了一个“临时”密钥,允许应用运行一段时间而不返回。

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

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

除了已经说过的....

由于中间语言的问题,. net应用程序的任何使用本质上都是容易被破坏的。对. net代码进行简单的反汇编就可以向任何人打开您的产品。他们可以很容易地绕过你的授权代码。

你甚至不能再使用硬件值来创建键了。虚拟机现在允许人们创建一个“许可”机器的映像,并在他们选择的任何平台上运行它。

如果软件价格昂贵,还有其他解决方案。如果不是,那就给普通黑客制造足够的难度。接受这个事实,即最终会有未授权的副本出现。

如果你的产品很复杂,固有的支持问题将为你创造一些保护。

要做到你所要求的一切,唯一的方法就是要求互联网接入和服务器验证。应用程序需要使用密钥登录到服务器,然后需要存储会话详细信息,如IP地址。这将防止密钥在多台不同的机器上使用。这通常不太受应用程序用户的欢迎,除非这是一个非常昂贵和复杂的应用程序,否则不值得这样做。

您可以只拥有应用程序的许可密钥,然后检查客户端密钥是否有效,但是很容易将此密钥分发给其他用户,并且可以使用反编译器生成新密钥。

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

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

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

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

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

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