I've written a Java Applet and run it from my website.
In the long-term I plan to charge money per use of this applet.
The question is, is it possible to prevent users of downloading my code (i.e. my jar file) and then running it from their home, without paying?
(In this I don't mean decompile - I use obfuscator. I mean someone can use it easily without even decompiling it or understand it's code...)
I thought about using a changing password which the server sends to the applet using the HTML, but I thought - maybe someone knows a standard way of achieving my goal instead of reinventing the wheel??
Thanks..
There are several ways you can do this.
You can put code like this at the beginning of the applet's init method, assuming it creates some components:
if (!getDocumentBase().getHost().equals("yourhost.com")) {
JOptionPane.showMessageDialog(this, "You can't download it");
return;
}
Of course, you have to change yourhost.com to your actual website.
Pros:
Easy to implement, no server-side code
Cons:
Can be decompiled and the test can be removed
Someone could trick their computer into thinking it is "yourhost.com"
You can put all of your code on the server. For this, I will assume that your applet computes the cube of an integer.
Then the code looks like this for your applet:
public class CubingApplet extends JApplet {
private JTextField intField = new JTextField(3);
private JLabel output = new JLabel();
public void init() {
setLayout(new GridLayout(2, 2));
add(new JLabel("Enter an integer: "));
add(intField);
add(new JLabel("The cube of that is: ");
add(output);
intField.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
output.setText("" + getCube());
}
};
}
private int getCube() {
try {
int n = Integer.parseInt(intField.getText());
InputStream response = new URL("http://www.yourhost.com/dosomething.php?n=" + n).openStream();
String sResponse = new BufferedReader(new InputStreamReader(response)).readLine();
return Integer.parseInt(sResponse);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
I must stop writing this right now, but I will add server-side code at the earliest opportunity.
By the way, even if you obfuscate, and it can't be decompiled, it is possible to recognize what these kinds of protection schemes look like, and remove them. So any protection scheme you devise can be short-circuited, because no obfuscation is bulletproof.
If the user's computer does all of the work of the applet, then it is impossible to prevent them from downloading a copy of the code. The browser has to download the code in order to run it; all the user needs to do is tell the browser to save the file or to use another program that will. The only way to prevent the user from being able to use the applet offline is with DRM. Perhaps you can include a check to your servers to ensure that the usage is valid; while the program is free the usage would always be valid but later you could verify it online. This is vulnerable to decompilation and modification to remove the DRM. Another option is to do some of the computation on your server, using code that is never exposed, but this of course has the downside of requiring you to maintain servers to do the calculations, which can be expensive.
In short no. Anyone can look at the webpages source code, find where the applet is stored and directly download it. If your product is not limited to an applet then it would probably be better to have it as an executable and sell that.
If you really need for it to be an applet that is payed for every time without being downloadable you could run all the actual processing on a separate server, construct what the screen would look like on the server and then send that image to the client (whos is using the applet). You would then display that image on the applet. Bear in mind that if your program would accept user input the applet would have to send that input to the server to be processed to.
The best way to do this would be to have a program on the serverside that provides data that is necessary for the app to do anything useful. They are only allowed to connect the applet to this if they have purchased an account (they have to log in inside the applet).
Since this is enforced serverside, they cannot bypass the restriction.
This obviates the problem of them downloading and decompiling it, because they still have to have an account to make any use of the applet.
The downside is that will probably require some rewriting of the applet and the creation of an entirely new program for the server.
If you really wish to protect your source code, you can make use of J2EE and make servlets that run on your webserver. The great thing about this is that all the work is done server-sided, similar to using PHP. This means that the end user can only see the output of the program and can not access the program files themselves.
A great article to read on the subject of J2EE servlets can be found here:
Java Servlet
Here is a quote from that page, I think it is exactly what you are looking for:
The servlet is a Java programming language class used to extend the capabilities of a server. Although servlets can respond to any types of requests, they are commonly used to extend the applications hosted by web servers, so they can be thought of as Java Applets that run on servers instead of in web browsers.
If you will implement a login page before the user will be able to use the applet, then you will not need to prevent them from downloading it. Anyone who wants to use must register (buy) from you a username/password.
Additionally you have already using obfuscator to prevent decompiling, which means that it will not be that easy to modify the applet to bypass login.
Related
I'm making a system for an app, witch have for objective to allow the user to create custom script to interact with the program by handleing events and reacting to them by calling functions. The main program is wrote in java, but If want to allow the script to be wrote in JavaScript. What is the best way to do that ?
I've tryed to use the sockets to transfer data and events, but I thinks it's a bit overkill, because the app and the scripts are on the same machine. Does it exist a better way to do that?
If I understand correctly, what you want to do is called Remote Procedure Call and it doesn't help much that all your code (java and js) runs on the same computer. But you can probably at least get away without authentication or security.
There are a bunch of libraries that may save you some trouble. You may want to take a look at those options:
https://en.wikipedia.org/wiki/Remote_procedure_call#General
I only got the occasion of using one: json-rpc, which isn't necessarily the best option, but it is the only one I can give you more details about.
The specification of the protocol is available here https://www.jsonrpc.org/specification and there should be Java and Javascript libraries to ease the implementation.
For example:
Java - https://github.com/briandilley/jsonrpc4j
Javascript - https://github.com/jershell/simple-jsonrpc-js
Calling this Java hello method:
public String hello(#JsonRpcParam(value="message") String message) {
return message;
}
From your client, a call to hello would look like this:
var jrpc = simple_jsonrpc.connect_xhr('localhost:8080');
jrpc.call('hello', {message: 'hello world!'}).then(res => console.log(res));
Of course there's additional configuration, at least on sever (java) side to make this work.
I am looking for a way to find the name of the program (in my code) that will launch when an operating system tries to open a given file. I will not be launching the application I'm just looking for its name. Ideally the routine I'm looking for/building would take a filename and return a string. I am programming in Java 8 on Eclipse and need my jar file to stay cross platform.
Simplest solution I can find is to use SWT's class 'Program'. Although this assumes that I can correctly identify filetype which is another big can of worms I'm not going to into here.
String ext = extractFileType(filename);
Program p2 = Program.findProgram(ext);
if (p2 != null) programName = p2.toString();
But for a number of reasons I DON'T WANT TO USE the SWT library if at all possible. I'm using Swing and and I really don't want my clients to need to download a different application (jar) dependent on their operating system. I'm well aware that the underlying code is operating system/Window Manager dependent.
Anyone know of any other package besides SWT that already does this? I can't find one. Or similar enough I can strip the results to get what I want? Even if it's only for one platform? I'm experimenting with Apache Tika but I don't see anything helpful there.
Any hints on where to look to start write this myself? I know this entails reading the registry on Windows. I need this code to work on the most recent versions of Windows, and OS X. And eventually Linux but Linux windowing systems are not a priority.
Is there a way to link/load SWT in Eclipse to make the cross-dependent part of using SWT this code a little more lightweight and invisible to the end user? I'm not new to coding but am to using Eclipse.
Here is a quick description of my solution. I did a fair amount of hunting around and I deciding on simply using the JNA library. https://github.com/java-native-access/jna and writing my own native library on a Macintosh to get it to work.
Windows: Fairly straight forward usage of JNA. I'm calling FindExecutable & PathFindExtension from JNA.
public interface MyShell32 extends Shell32 {
MyShell32 INSTANCE = (MyShell32) Native.loadLibrary("shell32", MyShell32.class, W32APIOptions.DEFAULT_OPTIONS);
WinDef.HINSTANCE FindExecutable(String lpFile, String lpDirectory, char[] lpResult);
}
{
...
char[] returnBuffer = new char[WinDef.MAX_PATH];
shell.FindExecutable(filename, null, returnBuffer);
app = Native.toString(returnBuffer);
...
}
PathFindExtention() call is similar but returns a pointer so it's more straight forward.
Macintosh: I tried all sorts of things and finally decided to write my own tiny native library to call in objective C
rtnValue = [[NSWorkspace sharedWorkspace] getInfoForFile:filenameNS
application:&AStr
type:&TStr];
This library is tiny (but I may add to it if I need other native calls) but I need to write a C/C++ shell as well as the Objective C to get it to work. I then call this library JNA. Not that different from writing straight JNI but I found it easier to code.
public interface NSWWraper extends Library {
/** The instance **/
NSWWraper INSTANCE = (NSWWraper) Native.loadLibrary("NSWWraper", NSWWraper.class);
// CP_NSWWraper
Pointer FindFileInfo(String filename);
void FreeMem(Pointer memory);
}
I honestly haven't tested this calling this a large number of files so I don't know how much it slows down my code. JNA calls are supposed to be expensive. It's interesting timing on someone asking for my solution as I'd had to put this on back burner and only got it working on Windows yesterday. I was going to incorporate this into the rest of my project today.
Edited to add. I didn't use JINI because I found it's not being very well supported on a Macintosh anymore and JNA was the better solution for Windows and I had to use it anyway.
I'm developing GWT application which has many different forms. Visibility of these forms depends on type of authorized user. In other words, I want to do the following:
String type = rpc.getUserType(); // ask from server only ONCE
if(type.equals("advancedUser"))
{
ContentPanel advPanel= new ContentPanel();
add(advPanel);
}
if(type.equals("admin"))
{
ContentPanel adminPanel= new ContentPanel();
add(adminPanel);
}
My question is the following:
Is getting user type from server only once and using this variable everywhere safe? I mean is there any possibility to change this variable (if it stored on client side)?
My friend told me that GWT prepares html on server side, so I can safely store type in one variable and use it - nobody can acces it.
But i think, that i have to make rpc call before each construction like if(userType=blah-blah-blah) add(something) because I think that GWT translates my Java code to Javascript which runs on client side and all variables can be modified with programms like ArtMoney.
My question is the following: Is getting user type from server only once and using this variable everywhere safe? I mean is there any possibility to change this variable (if it stored on client side)?
Yes that is the most possible and Robust solution. More over I would like to suggest, make it static
public static String USER_TYPE = rpc.getUserType();
That variable should initialize with a value in very first of onModuleLoad and should be in to whole application.
But i think, that i have to make rpc call before each construction like if(userType=blah-blah-blah) add(something)
No that raises performance issues and unnecessary server calls through the wire.
because I think that GWT translates my Java code to Javascript which runs on client side and all variables can be modified with programms like ArtMoney.
GWT secure enough and compile your module with the option Obfuscated, which makes your code not human readable in browser.
That Obfuscation alone protect from all vulnerable things, there are some other steps also needs to be taken to sleep happy :)
I'm suggesting to go through the GWT security documentation.
Besides all,
While saving or processing data on serverside that check you done on client side needs to be done strictly, So that you cn avoid such situation.
On server side
if(clientsideUserType.equals(serverSideUserType)) //
{
// Then only insert/process data
}
I have a java applet I am using for uploading from interenet explorer in my web site.
when a button is presse on my site , a javascript function inits the applet and calls the applet's OpenPrivDialog() function.
public void OpenPrivDialog() {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
#Override
public Object run() {
OpenDialog();
return true;
}
});
}
public void OpenDialog(){
JFileChooser fc = new JFileChooser();
fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
fc.setMultiSelectionEnabled(true);
Logger.getLogger(UploadApplet.class.getName()).log(Level.INFO, "Opening dialog", "fe");
int retVal = fc.showOpenDialog(f);
if (retVal == JFileChooser.APPROVE_OPTION) {
Logger.getLogger(UploadApplet.class.getName()).log(Level.INFO, "approved", "");
File[] files = fc.getSelectedFiles();
Logger.getLogger(UploadApplet.class.getName()).log(Level.INFO, "got " + files.length+" files", "");
AddFiles(files);
}
}
this code works, but is terribly slow the filechooser dilog opens, but for a minute is completely unresponsive and then just extremely slow -any idea why?
When I read this post I could picture a horrible experience I had. I needed to work in a software much more complex than yours but in essence it had the same principle: Interacting Java Applet with Javascript running on a web browser.
We faced several issues and I would highlight:
Slow response: similar to what you are experiencing.
Security issue: security checks asking the user to agree with
potentially dangerous code and other issues related with
zero-day-attacks.
Inoperative Javascript calls: rarely our applet could not reach the
javascript code, we never found the reason of this issue and it was
very hard to reproduce.
Browser compatibility: Firefox and Chrome were very standard, but we
faced several problems with Internet Explore and Safari.
It turns out that our applet code was ready in 5 days but the integration with javascript took about a month (we had 4 senior developers working on it) just because our stakeholder wanted it to work with some fancy jQuery components. It was just a nightmare!
Bottom line, we could not do it. Alternatively, we wrote everything within our applet and provided a series of properties that UI developers could use to change the appearance of our applet which worked great and everybody was happy with it.
Therefore, I would advice to do not use JavaScript + Java Applets. Yes, you can use some basic features, but do not go further with it.
Alright, let's talk about your issue. We noticed in some cases that javascript was very slow when calling Java Methods but was never slow when changing Java Propeties. So, we created some Java variables and changed it via Javascript. Next, we watched these variables (maybe in a thread). Finally, we could call the right methods based on these variables.
No, I do not like this approach. But was the only thing that worked for us before drooping the idea of using Javascript with Java Applets completely.
I hope it helps.
Cheers,
It goes like this, we need to detect if the display is a Projector (or if the system is connected to a Projetor).
the catch is this should be done from within the browser.
so is it possible to do so by using an
Java Applet
Flash
ActiveX (this does constrains to a single browser, so not an option)
searching so far only reaveals display resolution. expecting if there is something still out there. . .
Edit: accecpted answer is for Java Applet approach. hope there may be an easier way through flash...
A normal Java Applet will not be able to tell you whether you're viewing through a projector.
If you can detect whether you're running on a projector from native code then you could code a library up to do so and access it from your Applet with JNI. You'll need to sign your applet and wrap your library loading with AccessController.doPrivileged()
Here's explanation of how that last bit works:
http://download.oracle.com/javase/1.4.2/docs/api/java/security/AccessController.html
By all accounts, Java Web Start provides an easier path for using DLLs from Java though:
http://mindprod.com/jgloss/jni.html#APPLETS
Use CSS.
selector {
property: value1;
}
#media projection {
selector {
property: value2;
}
}
You could use JavaScript to detect the different value. :)
if (element.getPropertyValue(property) === value2) /* Some JavaScript stuff. */