Java: How to check whether the computer has been changed [duplicate] - java

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to get a unique computer identifier in Java (like disk id or motherboard id)
I am creating a small Java program. In there, I am creating a file called "James.txt". I am using this file to check whether the program has been moved from James computer or not. What I have done there is, writing Jame's computer's IP address to that file. So, when he start the program in the console, it will first check the file and will say "Hey James! Suprise!!!", and if the IP isn't belong to james it will print "Sorry, This is for James Party".
But, the case is, IP address can be changed even in the same PC right? So, how can I uniquely identify James computer? Please help!

MAC Address will change if the NIC is changed. Motherboard may fail and be replaced. The same may apply to processorId, hard-disk id and stuff.
Bottom line -
Develop an identifier for your application
Have your application maintain an identifier on the user's computer
When your application asks the user to identify himself/herself with userid/password/biometrics, validate the identifier too and then display the message you must.

Technically, you can't uniquely identify any computer because everything can be 'spoofed'. You can even change your MAC address as easily as your IP if you know how.
That being said, some systems attempt to calculate combinations of values that together can be used to define a semi-unique instance. Generally these come from hardware identifiers, like:
MAC address
Hard disc identifier
CPUID
These are then mashed together in a way that provides a unique key with some tolerance for change (like a hardware upgrade). There is also a generated identifier used in some systems called UUID which is created when a filesystem is built.
To access some of these you may need to use JNI. Some of these are contentious (CPUID) because they can be used to track people on the internet and thereby reduce their anonymity.
Frequently access to these are unavailable from certain applications (like web browsers). It may be easier to establish a login/password form of security.

There is no way to guarantee a computer hasn't changed. Your best alternative is to write a key file to the machine on first run that you can then use to check against. Whilst this could be deleted making it appear to be different as long as you have used a sensible hash algorithm to generate your key (i.e. you can be confident no one else could generate it) then you can be happy that you are guaranteed a correct match when the key matches. This method will give you confidence in positive identifications but leave you open to false negatives, which isn't normally an issue. You should look to use something like an SHA algorth based off some salted input that you can use as a reference.

Anything you can do in pure Java won't be very effective against a tech-savvy user who deliberately wants to 'break the system'.
But, nonetheless, low-tech things that you could do in pure Java:
just go ahead and store the MAC address; it's not totally reliable, but most users in practice won't change their MAC address;
allocate a random UUID and store it on the machine using the Preferences architecture; then, store that UUID, or a secure hash of it, in the program's local directory.
Either of these systems is easy to get round by a savvy user. But at the end of the day, a savvy user could doctor your class files to bypass whatever measure you put in place.
The disadvantage of the MAC address is that there is a 'legitimate' case external to your program where the MAC address may change, since a user may change their network devices.

IP address might change quite often (e.g. assigned using DHCP)
I propose to use serial number of disk or motherboard for identification.
Example of how to get these serial number on WINDOWS can be found here:
http://www.rgagnon.com/javadetails/java-0580.html (includes source code, platform dependant)

You could use the Java registry to write a simple value into the system registry. This will work on Linux and Windows and is a very basic way to do this. Not secure and quite hackable, but at least it's portable.
You can refer to read/write to Windows Registry using Java for some great examples.

Related

Could I generate a UID based on system specifications in Java?

I am working on a MMORPG game built in java, with this the end user runs a java executable (client) on their system that connects to our game (server).
Sometimes you get some players that are less than nice, and require a ban, some people are however really persistant which require an IP ban, and then there is the third type of people that have above average knowledge of computers and know how to change (or mask using vpn/proxies) their IP.
To combat these last kinds of people, we used to generate a UID file somewhere in their AppData folder with a unique key generated when the client launches (if no file is found it will generate one for them, but the flaw here is that if someone finds this file, they could easily just remove it and on the next start it would recreate a new and different one for them)
A while back I read somewhere that Microsoft generates a "fingerprint" based on several system specifications which is pretty much unique for each system, but on regeneration will result the same key, this is why you can reinstall Windows 10 without ever having to use any serial key. Would a system like this be possible in pure java?
To summarize, we need a unique key for every machine it is being run on (or atleast a very very small chance of a duplicate key being generated), but should the generation code be run again it needs to generate the same key

Does Windows have a unique key/fingerprint, that won't go away after reinstallation?

I have a question that I couldn't find an answer online, so I decided to ask here.
Does Windows have a "Unique Identifier" per PC? That's not the CD-Key? If so:
1a. Is it possible to get and use that Identifier, legally?
1b. If I were to reinstall my PC, would that Identifier change? Or could I change it manually?
If not:
Is it possible to create a "Unique Identifier" that..
2a. Stays the same, even after reinstalling my PC?
2b. That can't be deleted/changed?
You might want to calculate the unique identifier from the hardware e.g. by reading drive serial number or network card MAC address. Reading this will usually require to execute a native command from Java e.g. on Linux to read drive serial number you have to:
udevadm info --query=all --name=/dev/sda | grep ID_SERIAL
Do remember that this identifiers can be changed by the user but in fairness so can anything else. If the users wants to spoof the identifier they will find a way.

How to "hide" sensitive system properties like passwords set by Java applications?

I am maintaining an existing Java product (which has a HUGE code-base). I discovered that it is setting (and getting) two of its internal passwords as Java system properties, at no less than 4-5 different places (methods). Now, the problem is, the passwords are being stored as plain text in the Java system properties, and so, the same is visible to external entities, as the application is not using any Java Security Manager. For example, if the application (process) is running on port number 1234, we can run the Java command:
jinfo -sysprops 1234
to view both the passwords as values of the corresponding Java system properties. I wish to ask if there is any remedy to this without changing the existing code-base too much? The desired effect would be to "hide" the two Java system properties (denoting the two passwords) from all external entities.
It may be noted that introducing a Java Security Manager into the application may not be a solution, as if we revoke read permissions from the said two Java system properties using the Java Security Manager, the application codes which read those properties would crash. Same is applicable for storing the passwords in encrypted form, as that would crash all codes within the application which are expecting to read the passwords in clear text form.
Since you said:
...at no less than 4-5 different places...
and you really don't want to do major code changes, I would:
Supply the password in an encrypted form.
Go through those 4-5 places (it's not so much!), and call a wrapper method that you have to write separately: MyPassUtil.getXYZPassword() which internally calls the System.getProperty() to get the encrypted password, decrypt it, and return the plain text version to whoever is calling it.
Keep in mind though, that this way, the decryption key and algorithm is stored within the application, and a good Java decompiler (JD-GUI or CFR) will still return this information. In other words, anyone with the access to the JAR file, can still get the information with some minor effort, something which I presume, since one can call jinfo, they can also get the JAR file.
The best is to use some form of keystore, which again, you can easily implement once you do the wrapper method mentioned in step 2, without affecting whoever is using it.
Also, some security tips:
If it's an SSH / SFTP connection, set up SSH keys between the two machines, and eliminate use of passwords.
If it's a database connection, at least configure the DBMS to allow connections only from this particular machine's IP address. If the connection is over the internet and you are behind an NAT, set-up a VPN first, and channel the traffic between the hosts through it.
For other setups, try and see whether there are some other tips you can do similar to these two points, to improve the security around these passwords.

Java - Determine if two visitors are similar (web-based application)

I have been searching the entire WWW for a week now to no avail.
Here's the scenario in bullet:
Application is web-based
Technologies are Java, struts2, Spring
Problem/Requirement:
When a user registers in our website, I must know if the user has already registered before (but is now using a different login id). Note that the system will not ask for any personal information from the user (e.g.: Real Name, Address, Birthday, etc.)
I've tried:
Limiting using IP address.. But IP addresses aren't fixed. They always changed.
I was planning to use MAC Address. Basically MAC address can be changed, but if I remember correctly, common users can not just changed their MAC address unless they really know what they are doing... in that case, it is okay.. although limitation using MAC address is not 100%, at least the common users do not know how to change their MAC address, so as of the moment, me and the client agreed to use the MAC address.. However, I do not know how to retrieve the MAC address of the client's computer/laptop... and as I searched further, it is impossible to do so..
So I wanna know if there's a certain trick to implement the said requirement... Note that the client just wants to prevent a HUGE number of users with multiple accounts in our website...
Can this be done? Note that I did not ask for this requirement, this is a client requirement and I am kinda at lost after few attempts so I want to ask experts if this is really possible.
The best way that I can think to do this is to use a combination of information that you can easily collect through the user's browser. You can then store that on a database and use it to determine unique visitors. Here's what you can collect.
Computer brand, OS, and OS version
Browser(firefox,safari,chrome etc..)
Browser plug-ins (this is pretty good because most people have hundreds)
Display information (screen size etc..)
This is pretty good as I believe only 1 in about 4 million people have the same browser plug-ins as I do.

Determining the physical location of a file and the device status in Java

I'm writing a program that has to mantain a large catalog of files. Those may be on different devices and I'd like to know what is the best way to do this in Java. I mean that I need to:
Identify the device the file (or just a directory) is on and get a name or identifier for this device that will be consistent...
Be able to use this device identifier to check if the device is plugged (like a USB pen, a HDD mounted or not, a network drive...)
Having this compatible with Windows, Unix and whatever...
The ideal solution would be some kind of device abstraction... In the docs I can see that File is related to partitions but it doesn't seem to be a proper abstraction or object of the filesystem. Or maybe if there is not a proper java abstraction, the best way to handle this diversity on each system.
Java 7 has the Path class which is an improvement over File. Check it out at http://download.java.net/jdk7/binaries/, or the tutorial at http://java.sun.com/docs/books/tutorial/essential/io/fileio.html.
If it is acceptable to (a) run only on Windows and (b) require admin rights to run your program, then this can be done with WMI via JACOB.
In particular take a look at the Win32_LogicalDisk class. This is sufficient to get the drive type (IDE, network, USB etc), the volume label and volume serial number (which may be enough to uniquely identify a removable volume for the purposes of your application.)
For more advanced functions (e.g. getting drive serial numbers) there are other classes, e.g. Win32_DiskDrive, Win32_DiskPartition, Win32_PhysicalMedia. However these will only work fully if running as admin.
A quick google turned up http://today.java.net/article/2006/07/05/java-and-usb which may be of help. At least it describes the state of USB support from a few years ago.
I would attempt to largely avoid the problem, by simplifying aspects of it. Namely I would would keep your catalog at the file/folder abstraction and then use the above article to generate code that listens for any USB activity.
Of course such an approach would require you to check a specific file/folder exists prior to the loading that portion of your catalog. Also you would require a thread to constantly listen for USB events and then perform the neccessary checks if any USB device has been connected/disconnected and perform the neccessary checks on the filesystem again.

Categories