【问题标题】:How does the keygen-sh offline-license-check validate the expiration of the license?keygen-sh offline-license-check 如何验证许可证到期?
【发布时间】:2021-04-13 16:33:04
【问题描述】:

我编写了一些希望出售给最终用户的软件,并且正在调查许可证服务器。 Keygen-sh 在他们的网站 (https://keygen.sh/docs/validating-licenses/) 上提到了当用户在尝试使用 keygen 的服务器验证他们的许可证时要做什么。我对选项三感兴趣:

验证请求失败,例如超时

失败可能是因为 原因有很多,但最可能的罪魁祸首是您的用户 没有有效的互联网连接。你可以处理这个 方法多种多样,但这里有一些想法:

  1. 开始宽限期(例如 30 天或 5 次额外的产品使用), 如果许可证验证有,则您不允许访问该产品 在那个时间范围之后没有成功。你应该清楚地告诉你 用户应该尽可能连接到互联网并 提前了解宽限期。

  2. 立即禁止访问 产品。这应该小心使用,不推荐,除非 您的产品依赖于有效的互联网连接。

  3. 回退到 如果您以加密方式使用,则离线许可证密钥验证 签名或加密的许可证密钥(有关更多信息,请参阅 API 参考 信息)。

在选项 1 的情况下,我应该如何检查自上次活动互联网连接以来是否已过去 30 天?如果我将最后日期存储在 .txt 文件中,他们可以简单地删除该文件。

这让我想到了选项 3。但是密码检查如何验证过期?代码 (https://github.com/keygen-sh/example-python-cryptographic-verification) 似乎没有使用系统时间。

我知道我无法阻止我的软件被破解。但它不应该像删除文件或切断互联网连接那么容易。假设他们不会篡改系统时间,也不会反编译我的代码。

【问题讨论】:

  • 选项 1:是的,他们可以删除它,这就是“提前”的意思。选项 3:您的加密签名许可证必须包含过期时间戳,是的,您必须将其与以某种足够安全的方式获得的当前时间进行比较。

标签: cryptography licensing


【解决方案1】:

我是 Keygen 的创始人 — 让我试着澄清一下这里的选项。这些选项实际上并不相互排斥,因此您可以同时执行选项 1、2 和 3,具体取决于几个变量。

你的想法在这里或多或少是正确的。您可以将日期时间存储在 txt 文件中,或存储在其他一些存储方式中,但正如您所说,它存在篡改的风险。为了防止这种情况,我通常建议做的就是许可验证缓存。这是缓存成功的许可证验证请求以供以后使用的地方,以及请求的加密签名。

这里有一个例子是 Node:https://github.com/keygen-sh/example-validation-caching(我知道你使用的是 Python,所以请耐心等待。)

本质上,当您执行许可证验证请求时,您可能希望将响应正文缓存到文件系统中,例如一个名为cache.json 的文件,以及缓存响应正文的加密签名,在响应的X-Signature 标头中可用,并将其存储到文件系统中,例如也许是一个名为 cache.sig 的文件。

当没有可用的活动互联网连接时,您可能想尝试从该缓存中读取数据,如果数据存在,您将使用 RSA PKCS v1.5 填充以加密方式验证缓存的数据和签名(类似于您链接的示例) 以确保它没有被篡改(即您提到的将原始日期时间存储在txt 文件中的问题)。如果缓存数据存在,并且在验证其真实性后,您将解码缓存的 JSON 数据并检查过期时间。

现在,如果没有有效的 Internet 连接并且缓存不存在,那么您可能希望转到选项 2,即禁止使用该程序,因为没有证据表明曾经提供过有效的许可证密钥.或者,我们可以利用选项 3 并提示输入加密签名的许可证密钥并在离线环境中进行验证。

如果您确实选择了选项 3,因为您似乎也想离线检查过期时间,您需要在许可证密钥本身内嵌入过期时间戳。因为 API 不会自动将任何数据嵌入到加密签名(或加密)的许可证密钥中。在没有任何缓存的完全脱机环境中,您将无法从 API 访问完整许可对象,这意味着您只能拥有嵌入在密钥本身中的数据。

我继续为您创建了一个在 Python 中执行此操作的示例:https://github.com/keygen-sh/example-python-offline-validation-caching

【讨论】:

    【解决方案2】:

    我已经将@ezekg 的cmets 塑造成一个Python 包keygen_licensing_tools。安全缓存请求就像

    from datetime import datetime, timedelta
    from keygen_licensing_tools import validate_license_key_cached
    
    out = validate_license_key_cached(
        account_id="your accound id",
        key="the license key",
        keygen_verify_key="your Ed25519 128-bit Verify Key",
        cache_path="/tmp/license-cache.json",
        refresh_cache_period=timedelta(days=3),
    )
    
    # out.is_valid
    # out.timestamp
    # ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-01
      • 2023-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-20
      • 1970-01-01
      相关资源
      最近更新 更多