Just a quick question about the use of encryption for app data.
Say you have a mobile app, this app needs to store some potentially sensitive data. In this case, a list of corporate ip addresses that need to be kept hidden.
The obvious answer would be to encrypt with the hash of a user's password. However in this case, a user account is optional and so a password may not exist. What would be the next best method of encrypting the stores data?
My first guess and probably the least secure is a key built into the application, but issue here is risk of different attacks that could see that password recovered.
Next guess would be finding some sort of identifier of the device that can be used as a seed for a password generator. Again seems like a flawed method.
Last idea is to securely randomly generate the password and store it encrypted with one of the above methods.
Am I following the right train of thought or am I way off?
I have a decent understanding of cryptography algorithms but finding the right application has me scratching my head. Any help would be much appreciated.
Thank you
The point is: as long as your data only resides on the mobile device, in the end, you are limited. In that sense: if you need to store information in a secure and reliable way, then you should consider a "server side" solution.
If that isn't possible, the next best thing is to have your app ask the user for a distinct password - which is then used as key as outlined in your question. You definitely do not want a single generic key that works for all users/devices.
But of course - asking the user to type a special password each time he wants to use the app will not be a solution your users will like. So you will have to offer the user to store that password somehow - which again increases the range of potential attacks.
Long story short: without a "remote" service you simply have to balance "user experience" with "enough security". Depending on your user set, you have to determine what is more crucial to these people - security or convenience.
Next guess would be finding some sort of identifier of the device that can be used as a seed for a password generator. Again seems like a flawed.
--- ?
You can encrypt it with the hash of ANDROID_ID or UUID in place of password
What's your opinion on this?
Related
I know that char[] is preferable over String when it comes to passwords, due to the fact that String is immutable. But I have not been able to figure out how to pass it to a prepared statement. Consider this code:
Connection con = MyDBManager.connect();
PreparedStatement stm = con.prepareStatement(
"INSERT INTO my_table(username, password) VALUES(? ?)");
String username = "Jonny";
stm.setString(username);
char[] password = new char[] {'a','b','c','d'};
stm.SetString(password.toString());
It works, but I suspect calling password.toString() defeats the whole purpose of using a char[], so how should I do?
And yes, I know that a password should not be stored in clear text. The password is hashed, but I still want to use the benefits of a char[]
This seemed to work, and I also changed the field in the database from text to bytea and (I think) should in theory give the same benefits as the char[] is supposed to, but I get a strong feeling that I'm not doing it right:
byte[] password = new byte[] {'a','b','c','d'};
stm.SetBytes(password);
Maybe I'm completely wrong in my approach, but my requirements are that the password hash should never exist in an immutable object. I am open to other ways of sending it to the database than PreparedStatement
Answer to comments:
I have learned a lot from #rzwitserloot's answer, but unfortunately it does not help. Never having the password hash in an immutable object is a non-negotiable requirement.
Why are passwords in char[] form?
I know that char[] is preferable over String when it comes to passwords, due to the fact that String is immutable.
If you mean: So now you can't change passwords. That's incorrect.
Perhaps you are referring to the fact that you can't wipe them clean', but just in case you aren't, let me explain that:
There is only one reason that char[] is preferable over String, and it is highly dubious: With a char[], you can 'wipe' the array out. That is, once your process (your java code) no longer needs the password, you can explicitly run Arrays.fill(thePassword, (char) 0); and now RAM no longer contains the password. You can't do this with string - you can null out your reference, but that's just 'wiping out the treasure map'. It's not digging up the treasure and smashing the treasure to bits. Someone willing to dig up the entire beach is still going to find it.
This sounds great, and is the only explanation for why a whole bunch of password-based APIs deal in char[] and not String. HOWEVER, this is extremely dubious as a principle and you should absolutely not rely on it:
If some other process that you cannot trust has access to your process's memory you are quite hosed already. You should fix that at the source, and not try to mitigate this problem by reducing your exposure. That's akin to having a giant gaping hole in your artery and fixing it by hooking up a constant supply of blood bags (fighting symptoms) instead of bandaging the wound (closing the actual hole). If somehow the hole cannot be closed, I guess the symptom fighting is better than nothing, but it's a poor alternative.
You have no actual guarantee, between OS and CPU caches, that wiping out your char array gaurantees that the password is no where in any part of the hardware that a hacker could feasibly get at.
For what it is worth, I would not judge any code that stores strings in passwords as insecure. In fact, I dread code that stores them in char[] form - I fear that the authors will misunderstand the protection that this gives, or that they straight up forget to zero it out: It's making readers of the code make false presumptions (namely, that the password is wiped out, which may not be true, and that this means that the password is not recoverable if anything manages to get a dump of the memory contents, which also probably isn't true).
NB: With security it's a good idea to get into the habit of writing James Bond film scripts. Here's a film script for you:
You run your server in a cloud hosting environment, on a virtualized PC. The operator of this cloud messed up, and upon server deletion (which is really just the termination of a virtual PC running on a host that is running hundreds of PCs), they do not wipe out the memory of the process. Somebody decides to try to abuse this: They ask the cloud hoster to give them a PC with linux on it, they then install a simple app that scans the virtual PC's own memory for anything that looks like a password and reports back, then shuts the machine down and terminates it, and asks for another one.
By using char[] AND wiping out the password, you're more safe against this.. but not if the server just crashes or gets hard-killed _which is exactly how e.g. Amazon EC2 is supposed to be used (see netflix's chaos monkey documentation, which the community at large generally agrees is the right way to do things), in which case there's a risk some password just so happened to be in char[] phase. Not to mention all the other places in memory these can end up in.
See how bond-level scripts help clarify matters? It shows there is SOME point to wiping out char arrays, but it's not foolproof.
How do I store a password in postgres
hashing it is also no good. At least, depending on what you mean with the word 'hash'.
The proper approach involves 2 things:
A 'salt' - the problem is, a LOT of people have iloveyou as a password. It doesn't matter what hashing algorithm you use, hashing algorithms by their nature hash the same input to the same output, so all I need to do if I get a complete dump of your DB is to run SELECT passhash, COUNT(*) AS ct FROM accounts GROUP BY passhash ORDER BY ct DESC LIMIT 1, and voila - that hash? That's iloveyou, and I can then do SELECT username FROM accounts WHERE passhash = ?, and everybody in that list? I can log in as them with pass iloveyou. Simple as that. A salt solves this problem: the idea is, you generate a random number for every account (upon account creation), you then store this random number in the database. The hash you store is the result of hashing the value: CONCATENATE(salt, password). Now every user that is an idiot and uses iloveyou as password ends up with a different hash. To check a password, you take the password as entered, retrieve the salt, recreate CONCAT(salt, pass), hash that, and confirm it matches the DB entry.
You want a hashing algorithm that is slow and weird. SHA-256, for example, is used by bitcoin, so there are a ton of dedicated machines out there that can generate billions of hashes a millisecond for SHA-256, and there's specialized hardware out there (hardware you don't have) that is far faster at it than any computer you own. That's bad, you don't want the hacker to have an advantage. So, you want a hash algo that is really slow, and is not (easily) optimized for custom hardware. BCrypt, SCrypt, and PBKDF are the commonly used variants for this. They're all fine (BCrypt is older and in that sense 'worse', but also simpler and proven. Pick whichever one you want).
Note that most libraries out there will take care of the whole salt business already, no need to explicitly generate and store these (the APIs of these libraries are simply: "Give me a thing to put in a DB for this password" and "The user entered this password, and this is the thing you told me to put in the DB earlier. Is it a match?". 'The thing to put in the DB' contains both the salt and the hash result combined into a single string.
Okay, so how do I get this 'thing to put in DB' that the bcrypt lib gave me to postgres?
It's going over a wire or at least a local socket, into the postgres WAL log, which then goes everywhere. The thing is also literally right there in the DB.
The notion that you can somehow eliminate this hashes value from your system hardware is completely impossible.
So just make a java.lang.String. It's fine.
I am creating an REST based web application which, after successful user credentials validation, generates auth token and authenticates subsequent requests using this auth token.
The contents(although not fixed yet) of token are
AES_encrypt{username:SHA_256(username,user_specific_salt):timestamp:expiry_period}.
To avoid db call, I am trying to generate salt value based on username itself.
Also, I am not sending salt value to client.
The problem is, I am a bit confused about the solution since the articles I have read so far suggest not to generate salt values on the fly but store at db level. Can someone help me figure out the optimal solution for the above scenario?
It depends on the use-case and level of the security concerns. Having safely stored passwords hashes is of course more important and sensitive than for example authorisations tokens for a web-service of limited functionality.
So the analysis is based on potential risks/benefits of particular solution.
Firstly, look what would happen if you were not using salting at all. Then if someone captures your token and knows its structure (username plus timestamp) may try to recover the key used for the encryption. It is a computational challenging task but in principle possible. Having access to only one or many tokens generated in the same way does not make this task much easier (I may be mistaken, they may be some loop holes in the AES encryption).
The aim is to get your key used for the encryption so that attacker may produce its own valid token for arbitrary user later on.
hacker needs to crack the key
You add a salt, even a fixed one for all the users.
Hacker still has to crack you encryption key, same as before. Once it has it
He takes old token, and updates the timestamp and the job is done. He just copies the original hash. as the timestamp was not hashed useing the salt, so it is not affected.
So lets assume you hash username+salt+timestamp. Otherwise salting is irrelevant as explained above.
So the hacerk needs to crack the salt so it can reproduce the correct hash. Having multiple hashses encoded with the same salt makes it easier to recover the salt. SHA is fast enough to allow brute false attacks nowadays.
hacker needs to crack the key
hacker needs to get one salt from all the hashes
By salting you introduced one extra step for the hacker to deal with but not a difficult one.
You add on the fly generated salt,
Hacker cracks the encryption. Then he needs to crack multiple hashes to recover few salts. He needs to guess the salt generation pattern to fake the token.
hacker needs to crack the key
hacker needs to recover multiple salts from the hashes
hacker needs to deduce the salt generation pattern.
Knowing the pattern it can produce the tokens for any user. Without knowing the pattern it can produced tokens for the cracked users, it is probably enough for the hacker.
Randomly generated salt stored in the DB, one salt for user.
hacker needs to crack the key
hacker needs to recover salt from the hashe
Hacker cannot create tokens for any user, but once knowing the salt it can create token for the hacked user. The DB stored salt does not improved things much, just prevent arbitrary user access but it still allows 'cracked' user access.
Randomly generated salt stored in the DB and changed regularly (hourly, daily).
Now hacking the salt once, does not help in the future, as it will not match the new salt value. Cracking hashes takes longer than hour. So hourly update should be enough. But tricky to implement it correctly, so that the valid tokens would not expire upon salt update.
So depending when you are on the scale of security paranoia and how important is your service you may step up the costs for the hacker.
I would say for your usecase, hashing with salt on the fly is completely fine just do add the timestamp to the messaged hashed, otherwise hashing has no effect.
Now, to prevent your secret key being discovered, you may considering salting our encryption key. That way if the encryption is cracked only for one user not all. But again if it is not banking applicaton, probably not worth it.
I know enough about cryptology to make life difficult for a novice programmer and get laughed at by security experts. So with that in mind, I ask: how secure is javax.crypto.Cipher? I realise that anything can be cracked by someone with a will and a way, but I still would like to know relative details.
The reason I ask is I would like to store account names and passwords that will be sent through my Cryptor class that will encrpyt them, and would like to know if this will do the job. If any one has any literature that I could read, that would be greatly apprieciated.
Thanks ~Aedon
Cipher is a generic class to apply an encryption/decryption algorithm. Its security depends on the actual encryption algorithm used (DES, triple-DES, AES, etc.), on the size of its key, and on the block chaining type that you choose.
If you intend to store passwords securely, then your requirements are quite different from simply "communicating securely/privately". A Cipher on its own is not enough to protect you. You need to use one of these
bcrypt
scrypt
PBKDF2 from PKCS#5
in that circumstance. Here are some arguments and links concerning password security.
The punchline is that "normal" encryption (or hashing, too) is just way too fast to hold off serious attackers. You want to artificially slow down the entire process to make it as hard as possible for somebody systematically attacking your application. A single user won't notice the difference between 1 or 500 milliseconds when entering a password but for an attacker this means that in order to break your scheme it will take them 500 times as long on the average - so if it would have taken roughly 1 month to find a valid password before, now it will take 500 months.
Since NullCipher is a Cipher - not secure at all.
I am developing an android app that requires multiple default passwords to be stored.
Based on the password entered, the user will be shown different forms to be filled.
What is the best solution to store the default passwords if the number of default passwords are more say 10 to 20?
I see two possibilities:
Hash all passwords (together with a salt!) and store the hashes in the normal sqlite database. Each time a user enters a password, you would generate the hash (with the salt) and look in the database if there is a mathing password hash. If no, no password was right. If yes, you can look which of the passwords matched, and forward to the correct form activity. Note that only one hash has to be performed when the user enters a password, so you can use slow hashing algorithms.
Store passwords in an (AES-)encrypted database, or in encrypted form in the normal unencrypted database. You can then always calculate the plain-text form of the stored passwords, for easier comparison. This approach has the downside that you would have to store a secret (key or passphrase) within your app (or get it from your server each time), which is easy to retrieve by decompilation - if these are sensitive passwords or you protect sensitive data, that would be a no-go.
I would prefer the first possibility. Also, I would not use common MD5 as hashing algorithm, but at least SHA-512 or, even better, bcrypt. Here is a good thread explaining why and how to do that on Android: Stackoverflow-Thread. Basically, you must reckon that somebody will retrieve the sqlite database, and it's then very easy to find out weak passwords (with the help of rainbow-tables) if fast hashing algorithms (e.g. MD5) have been employed. Password salts do help, but only against google attacks. Bcrypt hashes (+ salt!) are much slower to generate (which is good), making even weak passwords hard to crack.
There are many storage options available in android. See this
If the data is limited then you can go for preferences.
Background:
I have been working on an Android application that stores data in a local database as my pet project. Lately, I have decided that I want to password protect the application and encrypt the database. Now, I am aware of the complexities of encrypting the database on the fly and have (given the expected usage pattern of my application) decided to just encrypt the whole database file rather than try to store encrypted column value or the like. Thus far I have implemented a system that will prompt for a password on every application launch or whenever the user navigates away from my activity (to account for the user pressing the home key and the application not being killed in a timely manner).
Currently, I am trying to decide how exactly to go about hashing the password and where to store it. Given that everything must be stored on the device, I am basically treating the password hashes and salt as already compromised as anyone who has spent 10 minutes reading can root a given device and access my database / preferences.
I have developed what I think should still provide very strong security given the above assumptions. I wanted to get some feedback from the community to see if my solution is viable or if there is a better way.
My idea is to generate 10 different random salt values on the first run of the application. These values will be stored with the actual final password hash in the application preferences (rather than in the database). Note that there will only be one password and it is used for both user authentication and database decryption. Whenever a challenge is presented, the password will be hashed as follows:
Cleartext password is hashed.
Hashed password is run through the same checksum algorithm that is used for standard UPC barcodes. This will result in a value between 0 and 9 (inclusive).
This checksum digit will be used as an index to the array of salt values. This single salt value will be appended to the current hash.
The new hash + salt value will then be hashed and steps 2 - 3 will be repeated.
I figure doing this process for 5 iterations would give 5^10 different salt combinations alone and should make any type of rainbow attack practically impossible. Once the final hash has been verified correct, it can be used to decrypt the database.
Now, I realize that this sounds like overkill for a simple cellphone app. It is. But, this being my pet project, why not?
Question:
So, after that wall of text, is this approach reasonable or is there a better way? I think, with this in place, the weakest link would be an in-memory attack or am I mistaken? Any feedback is greatly appreciated.
Thank you in advance.
-cheers
I don't get it. If you are encrypting the database, why do you need to store a hash of the password anywhere?
Derive an encryption key from the password, which is stored in the user's brain, using something like PBKDF2. Use it to encrypt the database.
When the user wants to decrypt the database, prompt them for the password. Derive the key from it again, and decrypt the database.
You store a password hash for authentication purposes. But this is encryption, not authentication.
Suppose you have a hash function that takes salt, a number of iterations, and a password as input, and returns a hash as output: byte[] hash(byte[] salt, int count, char[] password). Randomly generate one salt on the first run of the app, and hash the newly chosen password. Store this salt and the resulting hash in the application preferences. Then randomly generate another salt, and hash the password with it. Use the resulting hash as the database encryption key, but store only the new salt in the application preferences.
Later, when a user wishes to use the app, prompt for the password, and use the first salt to hash it. If it matches the stored hash, the user has proven that they know the decryption password. Hash it again with the second salt, and use the resulting key to decrypt the database.
This subsequent derivation of an encryption key might be what you meant; I am trying to make that step explicit, in case you intended to use the password directly as an encryption key. Having two different salts, one for authentication, and another for encryption, will allow you to use the same password for both purposes, safely.
What I do is use the record ID of the database row as the salt. You could hash the id of the row and use that for a zestier salt.
If you only have a dozen or so passwords, it seems approximately similar in security to what you are already doing. But if you have hundreds or tens of thousands, it becomes infeasible to calculate one dictionary table for every ID.
Ok... Assuming your hashing method is not weak, it doesn't matter if the salt is known - Salt is simply so that 2 users with the same password have different hashes - and a casual inspection of hashes wouldn't result in identical passwords being obvious. Salt should be unique per user.
Assuming the (malicious) user has root, there's absolutely NOTHING you can do to prevent them compromising your app except encryption - specifically the user could theoretically get your binary, decompile it to work out how it authenticates users, bypass it and then just follow the decryption mechanism - And since the encryption key is not related to user PW in your scenario, it has to be stored SOMEWHERE - and if the app can read it, so can root
The only truly secure approach would be to have a single-user (or at least single-password) which related to the DB encryption key.
Aside from that, the best you can hope for is to make it sufficiently difficult for a malicious user that it' not worth their time.
Even with 10 salt values you are still technically vulnerable to rainbow table attacks. All they have to do create 10 rainbow tables each using your salt. It will take them sometime to generate all new rainbow tables, we are talking days or weeks. Once they have the tables though the can use it against all the users who downloaded the application. If you store a unique salt per password that would require them to go through the whole process for every password, which is a lot of work for just one password. The question is would someone want to go through all that trouble to get one password. Here is a good post about storing passwords "You're Probably Storing Passwords Incorrectly"
I cannot spot any major weakness in this scheme. However, it does not add any security over best practice salting; i.e. generating an storing a new per-user salt each time the user sets or changes their password.
This scheme does add an extra point of attack. If there is a weakness in the way that the salts are generated (e.g. predictability), then it is likely to be easier to exploit if you restrict yourself to 10 salts all generated at the same time. That might give an attacker more leverage to guess what the likely salts are, and hence create rainbow tables.
But the main problem with your approach (IMO) is just the complexity.