I'm trying to develop a standalone software for windows in java. My goal is to have a completely standalone software which can encrypt some data and decrypt them when the user inserts a correct password. Following the standalone mindset I would love to avoid using some DB to store the data (mandatory installation of a MySQL DB sounds horrible to me), so I decided to store the data in a simple txt file, converting my java storing-data class to JSON and saving this string in the file. Obviously I would encrypt the string before saving it. The most weak part of my project (or at least in my opinion) is the login. I've come up with this idea:
using PBE from java.crypto to encrypt and decrypt data
a check string for checking the user password like "this is my check string"
I encrypt my check string using a particular algorithm, a particular salt and a particular first time password like "admin". Then I store my encrypted check string in a separate txt file. The first time the user execute the application he can log with "admin" password and then change it.
the authentication process is this: the user inputs his password, and my program tries to decrypt my check string using that password. If the decrypted string equals the original check string the log in is successful. On the contrary it gives an error message to retry cause the password is wrong.
My idea seems somehow solid to me (at least for a non professional point of view) but I've read that you can extract the source code from an exe file and this would mean that anyone can spoil my secret check string, my salt and my encryption algorithm (cause this data are all written explicitly in one of my java classes).
Since this is my first time with java.crypto and in general with a standalone authentication problem, I would love to receive some advices from someone more experienced. Anyway I have some experience with MYSQL and db in general, but I would love to have a light and not that expensive way to store data, cause i know that storing in txt files is quite "naive". Anyway I'm accepting any type of advice, especially cause I've no experience with this type of problem.
Related
I am trying to create a login and register page for my website. I am looking to use cookies in order to track a users session however I'm trying to implement it in the most proper and secure way. I've tried looking at tutorials and forums but most of them are outdated and use techniques that people comment are not secure. I understand tokens needs to be randomly generated and encrypted so I found one response that suggested to use a MessageDigest on UUID. But I found more articles suggesting that this may not be as secure as I think... Any suggestions on a secure way to generate cookie tokens to store in my db?
When I tried using the UUID method I got stuck on how to place it into my db since I'm having trouble finding how to turn it into a string. Here is my code...
UUID uuid = UUID.randomUUID();
MessageDigest salt = MessageDigest.getInstance("SHA-256");
salt.update(uuid.toString().getBytes("UTF-8"));
Your current method is, well, rather terrible. Consider if I, an attacker, learnt that my victims UUID is some value x. I could then simply take the SHA-256 hash of x and store this as a cookie on your website. Tada. I'm now impersonating my victim.
In saying that, a very secure way to produce tokens for login systems is something relatively similar. Consider the following JSON object:
{ "expiry": "1:30:00 24/10/2012", "userID": "F68D4A77DC34" }
If we stored this JSON object as a cookie on the client-side, it would be an excellent way to determine who our user is and when this object expires and the user needs to login again.
But wait, this won't work, because anyone could change the user ID or the expiry and your server won't know!
We can solve this easily by introducing an HMAC. An HMAC is a Hashed Message Authentication Code. We first generate (once, ever) a random HMAC key, k, to use on the server. This key should remain on the server and never be transmitted.
When a user logs in, we create a JSON object similar to the one above and then feed it through an HMAC (say, HMAC-SHA256) with k as the key, and then append the result of this to the JSON object as base64 encoded bytes. It sometimes helps to use a splitting character too, say ".".
We then end up with the following:
{ "expiry": "1:30:00 24/10/2012", "userID": "F68D4A77DC34" }.ScvlfpUDqgxtDPH4jsK44d+4cMNG+5yCvASJkVEI11o
This token would be fine to use exactly like that, but some people like to base64 encode the JSON too. We end up with something like this in that case:
eyAiZXhwaXJ5IjogIjE6MzA6MDAgMjQvMTAvMjAxMiIsICJ1c2VySUQiOiAiRjY4RDRBNzdEQzM0IiB9.ScvlfpUDqgxtDPH4jsK44d+4cMNG+5yCvASJkVEI11o
It is easy for us to verify that this token is legitimate by taking the JSON object, performing the same operation again, and then comparing the result of the HMAC with the one that is attached to the token. If they match, we know that our server generated the token and that it is legitimate.
There appears to be some misconceptions about what this "secure" token actually means.
It can be anything, in theory. You could use a username, or an incremental id counter, or salted hash of the username, or a uuid.
The question is what are you using it for and why?
If you're using it because you just want information on how long requests are taking, a number works just fine (in theory; not saying I recommend it, more on that later). You don't lose anything major if someone fakes the id number and why would they? They don't see an actual benefit from it.
If you're using this token because it determines who a user is for permissions purposes, then obviously your goal is to make it so it can't be faked. If you want it to be faked, then you should make it truly random and unique. So you could, quite easily, just use UUID.randomUUID().toString() - This is highly unlikely to be spoofable as someone would need to know the exact nano-second precision on your machine as well as the ability to know what the state of the random number generator for the other bits of the uuid are. And that simply won't happen.
I have the following three lines in my little game which store the id and pass of a new user:
Properties prop = new Properties();
prop.setProperty(id, pass);
prop.store(new FileOutputStream(new File("path/to/project/src/properties.data")), "");
Unfortunately I've noticed that only by changing the properties file extension to txt all the users and passwords become visible and readable by anybody, which is a thing I don't really like. Please let me know of a good easy method to encrypt the file in some way.
The thing is I already searched about this but the answers don't really fit my needs, I don't expect my game files getting attacked by the biggest hackers so using AES or any other big popular libraries would be too much I'd say. What do you think?
First, everybody can read your password file, no matter if the extension is .txt or .data or whatever else. The extension is just a Windows trick to decide with which program to open the file, but it does nothing to the contents.
If you want to encrypt the password file, you'll need a key and / or a password for that, and then you need to figure out where and how to store that. You just postpone the problem.
If the file holds names and passwords of the players in your game, go with #Boris the Spider's advice: instead of saving (encrypted) passwords, just save the password's hash. When someone logs in, calculate the hash of the entered password and compare that to the hash you have saved. If they are equal, the user entered the correct password. See this question and the accepted answer for a possible way to do this.
Here's an excellent article on storing passwords securely. The examples are in C#, not Java, but it's still a helpful discussion:
https://blog.mking.io/password-security-best-practices-with-examples-in-csharp/
I also strongly recommend the book "24 Deadly Sins of Software Security" by Michael Howard and David LeBlanc as a more general overview of common security bugs and how to avoid them.
I faced a similar problem and I took resort in writing an AES encrypted string in file (in my case, users were asked to take encrypted key from administrators to put into property files, so I provided a method to encrypt password to them too) and then decrypting it in the method where I am reading it.
I am developing an android application through which i am sending a mail via GMAIL API.
To send mail via GMAIL API i have to give them my ID and password.
GMailSender m = new GMailSender("myemailhere#gmail.com",
"mypasswordhere");
and i know writing password like this is not at all safe as my password could easily be stolen by extracting my apk and alsostoring the password in strings.xml is also not secure as xml can also retrieved.
my question is-
Is there any other way to write password in my file so that it remain secure??
The short answer is not. You shouldn't store your password anywhere in the code or in any file.
Even if you encrypt it like someone said you will have to store it's decryption algorithm/key somewhere in the code, which will be easily reverse engineered.
No,It's not safe to store passwords on the device.
small advice is always store passwords in char[] in encrypted form rather than storing in a String whenever it is mandatory to store.
Since Strings are immutable in Java if you store password as plain text it will be available in memory until Garbage collector clears it and since Strings are used in String pool for re-usability there is pretty high chance that it will be remain in memory for long duration, which pose a security threat. Since any one who has access to memory dump can find the password in clear text and that's another reason you should always use an encrypted password than plain text. Since Strings are immutable there is no way contents of Strings can be changed because any change will produce new String. So Storing password in character array clearly mitigates security risk of stealing password.
Storing passwords is not considered safe, and shouldn't be done if at all avoidable. There are a few considerations, if you have to for some reason.
The best place to store such things is in private SharedPreferences. These are not readable by anything but the app, or rooted devices. Do not store on external storage!!!
Encryption can always be undone, but if you have to, then it would be better than nothing, requiring more work to undo. Use a key which is unique to each device.
Some sort of a token, such as is used by Oauth, could be a solution. This isn't perfectly secure either, but it could be.
Google provides more secure APIs for it's functions. You really should look in to that.
This question already has answers here:
Handling passwords used for auth in source code
(7 answers)
Closed 7 years ago.
I need to hide the password in the source, what are the possible methods to obfuscate the password in order to reduce the risk of decompilation?
e.g.
final String password = "secret";
Don't bother.
Your average user won't be able or willing to decompile class files anyway, and a motivated and skilled attacker won't be held back by obfuscation when the target is a single piece of data. All it takes is one such motivated and skilled attacker and the whole world knows the password.
If your security depends on obfuscating a password, you have already lost.
First, I wouldn't name my variable password.
Second, I wouldn't keep it in raw format, but encode it.
Third, I'd use a char[] instead of String (because strings reside in the string pool).
Of course the best option would be to not keep it in the code at all.
Encrypt the password using an external method, a method that can be used decrypt within your code and store the password (encrypted) on your code
Use database or file to save your pasword. Here is pretty good post with example.
But still you need to store somewhere one master password to encrypt your passwords. Tt's hard to protect it from being found and misused to decrypt your passwords :(.
This question already has answers here:
Encrypt password in configuration files [closed]
(10 answers)
Closed 5 years ago.
I need to save a db password as an encrypted string and then decrypt before connecting.
Can anyone refer me a good two-way encryption library in Java?
Dan, take a look at this thread as there is some useful info on how to do that in a property file just via Java's APIs.
Encrypt Password in Configuration Files?
In real terms of security Base64 encoding will be almost as good as any "hard" encryption.
(Dispute in comments. :) )
Edit: OK, the recent downvote brought me back here to add some words.
The above statement is meant to remind people that it is impossible to have any automated activity authenticate in a secure way to some other party. If you'd use a password to encrypt and decrypt a stored password, where would you store this new password? Easy! Just make a third password to securely store the second password and so on.
Point is: Any password which is decryptable by some automatic procedure is in fact not encrypted but merely obfuscated. Thus, the encryption is futile in the first place.
Usually passwords are kept as hash, so the process of getting the real password is not possible, other than converting it back what we do is we convert the password user entered to a hash and then match them. If you can explain more about your usecase it'll be clear