10

我想制作一个只能在具有密钥或许可证的机器上运行的桌面应用程序。如何做到这一点?

4

3 回答 3

28

这完全取决于你想要让它有多安全......

Java的问题是你可以反向编译它。因此,如果有人愿意,他们可以下载您的软件,对其进行反向编译,然后删除您设置的任何安全性(然后如果他们愿意,可以重新分发)。

如果您计划进入大众市场并出售它,这只是一个问题,但盗版实际上是一个问题。

如果您不担心这一点,那么您可以在线或离线检查。

与我合作的公司使用在线方式;有几个步骤:

编辑:我已经改变了它的工作方式,因为旧的方式是维护的噩梦。

  1. 许可证文件
    • (这可以包含你在现实中想要的任何东西,它必须是每个用户唯一的。大多数人通常穿着一般的服装;
    • name
    • company
    • email
    • 然后一个key. 即JDU8-AJS9-88DF-SASF-ASF9你经常看到的那种东西。
  2. 该程序从许可证文件生成一个散列。
    1. 将许可证文件中的所有数据放入一个字符串中
    2. 将字符串传递给哈希函数,此页面可以向您展示如何。
  3. 让程序在线检查(在您的服务器上)。数据在 HTML 请求中编码(post/get/json/whatever you want)并提交到您的许可证验证页面,然后验证数据。数据中包含一个随机生成的字符串,验证页面使用该字符串生成另一个密码。然后将其返回给程序,该程序也使用随机字符串生成自己的密码。如果两者匹配,则程序启动。

要生成密钥,只需使用相同的散列函数,然后将散列上传到您的服务器。

如果你想让它离线,你可以在我猜的代码中包含哈希值并在那里检查它们。

但是,我应该指出,无论如何我都不是安全专家,我只是作为博士的一部分为公司开发。这就是我的做法。

编辑:这张图片可能会有所帮助:

在此处输入图像描述

第二次编辑:

我现在在这个过程中加入了“离线验证”。这不是真正的离线验证,它只是将用户用作代理——他们需要以另一种方式访问​​互联网。

它是这样工作的:

  1. 未找到互联网连接:向用户提供 4 位代码
  2. 用户进入离线验证页面(也针对移动使用进行了优化)
  3. 用户从下拉列表中选择他们使用的软件
  4. 用户输入他们的用户名(此字段记住条目)
  5. 用户输入程序给他们的代码并提交
  6. 网页提供了一个 4 位代码,然后他们将其输入到程序中,然后程序启动。
  7. 程序将一些特殊数据添加到许可证文件中,这意味着下周/月/无论多长时间都不需要重复此过程。

每次程序成功在线验证时,它还会在许可证文件中添加一个离线访问密码,这意味着它可以抵抗临时的互联网停机时间,并且只有在互联网停机超过一周/一个月/无论多长时间时才会停止工作设置为工作。

于 2012-06-05T12:00:33.243 回答
1

您可以使用 macIP 在线跟踪机器的许可。即使在 Windows 中,您也可以在注册表中写入没有 api,但您仍然可以这样做。在下面找到片段以读取注册表 -

public static final String readRegistry(String location, String key){
        try {
            // Run reg query, then read output with StreamReader (internal class)
            Process process = Runtime.getRuntime().exec("reg query " + 
                    '"'+ location + "\" /v " + key);

            StreamReader reader = new StreamReader(process.getInputStream());
            reader.start();
            process.waitFor();
            reader.join();
            String output = reader.getResult();

            // Output has the following format:
            // \n<Version information>\n\n<key>\t<registry type>\t<value>
            if( ! output.contains("\t")){
                    return null;
            }

            // Parse out the value
            String[] parsed = output.split("\t");
            return parsed[parsed.length-1];
        }
        catch (Exception e) {
            return null;
        }

    }

如果你想混淆使用proGuard在类级别。

于 2012-06-05T12:00:15.990 回答
0

这取决于您计划拥有多少客户以及分销模式。您可以使用许可证服务器,但这需要客户连接互联网。您还可以使用 USB 加密狗来管理许可。

没有完美的系统可以让您在简单、努力和价格之间做出折衷。

于 2012-06-05T11:43:24.693 回答