通过许可证或密钥保护Java应用程序

11

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


在线验证(例如在每次启动时)是一个选项吗? - nfechner
1
无论如何,我认为你的应用程序很可能会被破解,因为所有东西都在客户端。 - nhahtdh
@nhahtdh 虽然需要付出足够的努力,但这对于任何事情都是成立的... - will
@will:对于云服务来说,情况并非如此(除非你进行黑客攻击,这可能会引起人们追捕你)。 - nhahtdh
我知道,但他还没有说明这是客户端还是云端的。 - will
这是一个桌面应用程序,应该可以离线工作。 - Ahmed Aswani
3个回答

29

这完全取决于您希望使其有多安全...

Java的问题在于,您可以反编译它。因此,如果有人想要这样做,他们可以下载您的软件,反编译它,然后删除您设置的任何安全性(然后如果他们想的话可以重新分发它)。

只有在您计划进行大规模销售并且盗版实际上会成为问题时,这才是一个问题。

如果您不担心这个问题,那么可以选择在线或离线检查。

我工作的公司使用在线方法; 这里有几个步骤:

编辑:由于旧方式会引起维护困难,我现已更改了此方法。

  1. 许可证文件
    • (实际上可以包含任何您想要的内容,它只需要对每个用户是唯一的。大多数人通常会选择一些通用的东西;
    • name
    • company
    • email
    • 然后是一个密钥。即您经常看到的那种 JDU8-AJS9-88DF-SASF-ASF9 等。
  2. 程序从许可证文件生成哈希。
    1. 将许可证文件中的所有数据放入一个字符串中
    2. 将该字符串传递给哈希函数。此页面可以向您展示如何: this page.
  3. 使程序在线检查(在您的服务器上)。 数据以HTML请求的形式(post/get/json/任何您想要的)进行编码,并提交到您的许可验证页面,然后由其验证数据。 数据中包含一个随机生成的字符串,许可验证页面用它来生成另一个密码。 然后将其返回给程序,程序也使用随机字符串生成自己的密码。 如果两者匹配,则程序启动。

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

如果你想要让它离线运行,你可以在代码中包含哈希值并在那里进行检查。

然而,我应该指出,我绝不是一个安全专家,我只是作为博士的一部分为一家公司开发,并且这就是我所做的。

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

enter image description here

第二次编辑:

我现在已经将“离线验证”包含在流程中。它不是真正的离线验证,它只是使用用户作为代理 - 他们需要通过其他方式访问互联网。

它的工作原理如下:

  1. 未找到互联网连接:向用户提供一个4位数字代码
  2. 用户转到离线验证页面(也适用于移动端)
  3. 用户从下拉列表中选择他们使用的软件
  4. 用户输入他们的用户名(此字段会记住输入)
  5. 用户输入程序给他们的代码并提交
  6. 网页提供一个4位数字代码,然后他们输入该代码到程序中,程序就开始运行了。
  7. 程序向许可证文件添加一些特殊数据,这意味着这个过程不需要在下一周/月/任何长时间内重复。

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


@will 服务器应该在响应中返回什么?布尔值?某种密钥? - Tomas Bisciak
2
@TomasBisciak 如果你让它只返回一个布尔值,那么人们很容易就可以编辑他们的hosts文件(至少在Windows上),并运行一个始终返回true的小型服务器。请让它返回一些特定密码,这些密码是从你发送的随机密钥生成的。例如,在你发送的数据中,包括一个随机字符串,然后对其进行哈希处理并发送回哈希值。然后检查哈希值是否匹配。 - will
1
@TomasBisciak 这只是我们在这里的做法。我知道这并不能解决它对攻击者可见的问题。我知道有一些方法可以使用硬件的各种细节创建某种“机器指纹”,这比使用 MAC 地址更好(可以欺骗)。如果我们忽略反向编译等,那么只要使用足够强大的哈希算法,我认为应该没问题。 - will
1
@TomasBisciak 我不会说这很容易。我会说那些在几天内破解最新视频游戏的人只是非常擅长这个领域。他们可能也在这个行业工作,因此知道自己在做什么。去找一些盗版软件 - 我敢打赌你会发现最受欢迎的软件在第一天就被破解了,每次发布安全修复程序都是如此。然后再找一些小公司的随机程序 - 你不太可能找到任何有关它的东西(我想),只是因为对于那些知道如何破解它的人来说没有任何好处。 - will
@Will 非常好 :) 当许可证过期时,您会怎么做?我的意思是取消激活的程序是什么?在支付新许可证后重新激活呢? - Root
显示剩余9条评论

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


1
MAC地址虽然可以很容易地伪造,但如果您想选择这种方式,那么创建唯一的计算机指纹更为安全。 - will
你如何生成计算机指纹? - Subhrajyoti Majumder
好吧,这取决于你的意愿。我曾经和一家采用这种方式进行许可证管理的公司交谈过,那个人说他们使用了很多东西,比如MAC地址、硬件细节,也许还有IP地址(但是这个经常变化,所以这取决于你想要许可证如何工作)。就我个人而言,我只是跟踪各种细节,并且让它相对不受限制,但是我会时不时地检查这些细节,如果他们似乎在滥用它(这还没有发生过),那么我会切断他们的访问。 - will

0

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

没有完美的系统,您需要在简单性、努力和价格之间做出妥协。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接