如何创建 Java 程序的试用版

发布于 2024-08-31 04:22:05 字数 1435 浏览 11 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

jJeQQOZ5 2024-09-07 04:22:05

这里有一个想法:

  1. 创建一个在网络上公开可用的数据库(例如 SQL Server 数据库)。它将保留“试用版”许可证密钥的列表。购买产品时,您可以使用相同的系统获取完整版许可证密钥。

  2. 当您的 Java 软件首次运行时,它将创建一个试用许可证,并将其存储在数据库中

  3. Java 软件每次运行时都会检查有效许可证。创建许可证的日期存储在数据库中,因此客户端时钟设置为多少并不重要。

  4. 许可证过期后软件将停止运行

标准 Windows 软件可以查找 CPU ID 并将其用作许可证的一部分,这样每台计算机只能运行试用软件一次。 有谁知道是否有某种“JVM ID”可用于此目的?

也许有免费或开源许可相关的代码已经?

Here is an idea:

  1. Create a database (such as a SQL Server database) that is publicly available on the web. It will keep a list of "trial version" license keys. You can use the same system for full-version license keys when your product is purchased.

  2. When your Java software is first run, it'll cause a trial license to be created which will be stored in the database

  3. The Java software checks for a valid license each time it is run. The date that the license was created is stored in the database so it doesn't matter what the client clocks are set at.

  4. The software stops functioning when the license is expired

Standard windows software can look up the CPU ID and use that as part of the license, so that each computer can only run the trial software once. Does anyone know if there is a "JVM ID" of some kind that can be used for this purpose?

Maybe there is free or open-source license-related code out there already?

凉城已无爱 2024-09-07 04:22:05

为什么不将到期日期硬编码到试用计划中,这样您就不必继续支持它?你可以把它放在 main() 中。

// Die after October 1, 2010
Calendar expireDate = Calendar.getInstance();
// January is 0 (y, m, d)
expireDate.set(2010, 9, 1);
// Get current date and compare
if (Calendar.getInstance().after(expireDate)) {
  // Die
  System.exit(0);
}

这就是微软分发其大规模测试版软件的方式。他们只是给了它一个有效期。

如果您正在谈论防止逆向工程或修改代码,则不能。您可以混淆已编译的程序,但这不会阻止人们对您的代码进行逆向工程。

Why not just hard code an expiry date into the trial program so that you don't have to continue to support it? You could put this in main().

// Die after October 1, 2010
Calendar expireDate = Calendar.getInstance();
// January is 0 (y, m, d)
expireDate.set(2010, 9, 1);
// Get current date and compare
if (Calendar.getInstance().after(expireDate)) {
  // Die
  System.exit(0);
}

This is how Microsoft distributes their large scale beta software. They just give it an expiry date.

If you're talking about preventing reverse engineering or modifying the code, you can't. You could obfuscate the compiled program, but this won't stop the people who would be reverse engineering your code anyway.

伴我心暖 2024-09-07 04:22:05

我只会做一些非常简单且足够困难的事情,这样非程序员就无法弄清楚。

我想将程序首次以 64 位长的二进制形式安装到文件中时的毫秒数写入文件。并让你的主班检查并执行时间限制。是的,人们可以改变他们的时钟来解决这个问题,但实际上你无论如何都不想卖给那些人。还要确保当前时间严格在安装后 30 天内。大多数用户只需将时钟调回一年,并且它适用于大多数程序,因为他们只是做了一个简单的小于差异检查。您还应该检查从当前到安装的天数差异是否也大于 0。

如果您觉得您需要更多的保护,那么您遇到的商业模式问题不仅仅是软件问题。让它变得不可破解基本上是不可能的,特别是因为您只能提取和反汇编类文件。

I would just do something really simple and just hard enough such that non-programmers wouldn't be able to figure it out.

I would something like write to a file the number of milliseconds when the program was first installed in a 64-bit long in binary to a file. And have your main class check and enforce the time limit. Yes people can change their clocks to work around this, but really you don't want to sell to those people anyways. Also ensure the current time is strictly within 30 days of the install. Most users will just set their clocks back one year and it works with most programs because they just did a simple less than the difference check. You should also check that the difference in number of days from current to install is also greater than 0.

If you feel you need more protection than that, then you have a business model problem more than a software one. Its basically impossible to make it unhackable, especially since you can just extract and disassemble the class files.

定格我的天空 2024-09-07 04:22:05

尝试限制日期的问题在于,如果用户调回系统时钟,仅检查日期的简单解决方案很容易被愚弄。我和一个人一起工作,他保留了一个 VMWare 虚拟机,只是为了运行时间有限的软件。更好的方法是记录上次运行的时间,如果时间早于该时间,您就知道时钟已调回并且可以中止。问题是弄清楚如何将该文件隐藏在用户找不到它的地方并覆盖它。同样,在 VMWare 或 VirtualBox 环境中,用户可以回滚到较早的快照。

换句话说,你可以在某些时候限制某些人,但不能一直限制所有的人。

The problem with trying to limit the dates is that the naive solution of just checking the date is easily fooled if the person sets back their system clock. I worked with a guy who kept a VMWare virtual box just for running time limited software. A better approach would be to record the time of the last time it was run, and if the time ever goes before that time, you know the clock was set back and you can abort. The problem is figuring out how to stash that file somewhere where the user can't find it an overwrite it. Again, in the the VMWare or VirtualBox environment, the user could just roll back to an earlier snapshot.

In other words, you can limit some of the people some of the time, but not all of the people all of the time.

雨落□心尘 2024-09-07 04:22:05

我从事商业 Java 软件的工作,它受到保护。

在您的情况下,强制要求互联网连接是否可以接受?在我们的例子中,我们的软件只有在有互联网连接的情况下才有意义,因此我们可以通过简单地遵循以下原则来使逆向工程变得不可能:

使足够的计算部分发生在服务器端

攻击者对此无能为力,除了:

  • 重写在服务器端发生的软件部分

  • 盗版您的服务器

如果我们的潜在用户对我们的软件要求始终在线的互联网连接不满意,他们可以购买或盗版我们竞争对手的劣质产品。

可以这样想:没有人使用假的/生成的许可证密钥成功地在暴雪的 Battle.net 上玩游戏。

当然,盗版者可以尝试伪造整个战网,但是盗版版本将不允许人们玩真实的《魔兽世界》经济,也不允许人们在真正的《星际争霸》天梯上竞争,等等。

为什么没有人设法做到了这一点:因为暴雪让足够的计算部分发生在服务器端

足够多的计算发生在服务器端实际上意味着:“好游戏盗版者”。

我们越是进入一个始终互联的世界,就越容易保护应用程序免遭盗版。内容 (DRM) 也是如此,无论好坏。

I work on a commercial Java software and it is protected.

Is mandating an Internet connection acceptable in your case? In our case, our software only makes sense if there's an Internet connection and hence we can make reverse engineering impossible by simply following this mantra:

make sufficient part of the computation happen on the server side

There's nothing against this an attacker can do besides:

  • rewrite the part of your software that is happening on the server side

  • pirating your server

If our potential users are not happy with the fact that our software mandates an always-on Internet connection they can either buy or pirate one of our competitor's inferior product.

Think of it this way: nobody ever succeeded in playing on Blizzard's battle.net using fake/generated license keys.

Sure, a pirate could try to fake the whole battle.net, but then the pirated version wouldn't allow people to play in, say, the real WoW economy nor to compete on the real Starcraft ladder, etc.

Why did no-one managed to do that: because Blizzard made sufficient part of the computation happen on the server side.

Sufficient part of the computation happening on the server side effectively means: "good games pirates".

The more we move to an always-connected world, the easier it is to protect apps against piracy. Same for content (DRM), for the better or the worse.

哑剧 2024-09-07 04:22:05

我检查原子时间服务器在代码开头发送给我的日期。
然后,我会将该日期与特定日期进行比较。如果原子时间较小,则 System.exit(0)。

public static GregorianCalendar getAtomicTime() throws IOException {
    BufferedReader in = null;

    try {
        URLConnection conn = new URL("http://64.90.182.55:13").openConnection();
        GregorianCalendar calendar = new GregorianCalendar();
        conn.setConnectTimeout(1000);
        in = new BufferedReader(new InputStreamReader(conn.getInputStream()));

        String atomicTime;
        while (true) {
            if ((atomicTime = in.readLine()).indexOf("*") > -1) {
                break;
            }
        }
        //System.out.println("DEBUG : " + atomicTime);
        String[] fields = atomicTime.split(" ");

        String[] date = fields[1].split("-");
        calendar.set(Calendar.YEAR, 2000 + Integer.parseInt(date[0]));
        calendar.set(Calendar.MONTH, Integer.parseInt(date[1]) - 1);
        calendar.set(Calendar.DATE, Integer.parseInt(date[2]));

        // deals with the timezone and the daylight-saving-time
        TimeZone tz = TimeZone.getDefault();
        int gmt = (tz.getRawOffset() + tz.getDSTSavings()) / 3600000;
        //System.out.println("DEBUG : " + gmt);

        String[] time = fields[2].split(":");
        calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(time[0]) + gmt);
        calendar.set(Calendar.MINUTE, Integer.parseInt(time[1]));
        calendar.set(Calendar.SECOND, Integer.parseInt(time[2]));
        return calendar;
    } catch (IOException e) {
        throw e;
    } finally {
        if (in != null) {
            in.close();
        }
    }
}

I check date from what an atomic time server will send me at the beginning at the code.
Then, I will compare that date with a specific date. If the atomic time is less, then System.exit(0).

public static GregorianCalendar getAtomicTime() throws IOException {
    BufferedReader in = null;

    try {
        URLConnection conn = new URL("http://64.90.182.55:13").openConnection();
        GregorianCalendar calendar = new GregorianCalendar();
        conn.setConnectTimeout(1000);
        in = new BufferedReader(new InputStreamReader(conn.getInputStream()));

        String atomicTime;
        while (true) {
            if ((atomicTime = in.readLine()).indexOf("*") > -1) {
                break;
            }
        }
        //System.out.println("DEBUG : " + atomicTime);
        String[] fields = atomicTime.split(" ");

        String[] date = fields[1].split("-");
        calendar.set(Calendar.YEAR, 2000 + Integer.parseInt(date[0]));
        calendar.set(Calendar.MONTH, Integer.parseInt(date[1]) - 1);
        calendar.set(Calendar.DATE, Integer.parseInt(date[2]));

        // deals with the timezone and the daylight-saving-time
        TimeZone tz = TimeZone.getDefault();
        int gmt = (tz.getRawOffset() + tz.getDSTSavings()) / 3600000;
        //System.out.println("DEBUG : " + gmt);

        String[] time = fields[2].split(":");
        calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(time[0]) + gmt);
        calendar.set(Calendar.MINUTE, Integer.parseInt(time[1]));
        calendar.set(Calendar.SECOND, Integer.parseInt(time[2]));
        return calendar;
    } catch (IOException e) {
        throw e;
    } finally {
        if (in != null) {
            in.close();
        }
    }
}
骷髅 2024-09-07 04:22:05

关于类文件,您无法阻止对它们的访问,但您可以通过

Regarding the class files, you can't block access to them, but you can make their de-compiled version totally unreadable by obfuscation.

故事和酒 2024-09-07 04:22:05

有一个名为 Rampart 的产品,可让您为 Java 应用程序制作试用版。只需要几分钟,而且效果非常好。

您可以在 http://Rampartlicensing.com 找到它

There's a product called Rampart that lets you make a trial version for your Java app. It only takes a couple of minutes and it works pretty well.

You can find it at http://Rampartlicensing.com

话少情深 2024-09-07 04:22:05

我过去曾成功使用 True License 。它有试用期的支持。将其与混淆工具(例如 ProGuard)结合使用,肯定会让破解变得不那么简单。

I've had success using True License in the past. It has a support for a trial period. Use it in combination with an obfuscation tool like ProGuard and it certainly makes it non-trivial to crack.

夏九 2024-09-07 04:22:05

我建议功能限制。我几乎没有便利贴程序。该程序可以正常运行,但在未注册模式下您只能创建 10 个笔记。所以我尽量对用户友善。没有日期限制、烦人的屏幕或其他邪恶的东西。只有很小的状态行,有限制文本和注册按钮。

I recommend functional limitions. I have little post it note program. The program works fully, but you can create only 10 notes in unregistered mode. So i try to be nice to user. No date limitions, nag screens or someting else evil. Only small status line that has limition text and and register button.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文