i have a question regarding the following scenario:
I want to use jasypt to encrypt my password and use a certain salt for encryption.
Does it make sense(or is there any security implication) if :
I use password based encryption to encrypt the salt with a password that I get from an environment variable, that way i can have the encrypted value of the salt in a property file, get it from there , decrypt it via the password i get from the environment variable (actually i am going to have a EnvironmentStringPBEConfig object which in turn gets the environment variable from EnvironmentStringPBEConfig object and delete the environment variable once the EnvironmentStringPBEConfig is created) and finally use the salt.
Thank you.
Edit: please note that i would want to know if "hiding" the salt as described above is a good practice, i am not implementing such solution right now.
EDIT: Also please note the following recommendations from OWASP.
Recommendation: Make it hard to steal the entire salt
There are a number of additional recommended enhancements to the basic salting mechanism for consideration:
Have an additional 'system' salt that is a fixed value for the entire system. This should be stored in a configuration file somewhere. This fixed value would not have to be included every backup, making it even harder for an attacker to compromise all elements required to calculate the hash value properly.
Embedding a portion of the system salt in the source code. This wouldn't be that helpful for open source code, but for custom applications, having part of your system salt in the code would be yet one more item required by an attacker to calculate the hash value properly.
Generating a new salt for an account each time that user's password is changed.
Recommendation: Salt Isolation
An additional password storage defense mechanism involves storing the salt in a different location than the password hash. Use of the server's filesystem is one commonly used mechanism for salt isolation, assuming the password hashes are stored in different location such as a database or LDAP server. This defense mechanism reduces the risk of password theft when the database file is stolen, since the salts will not be included with the database data. Be careful to ensure that both the password hashes and the salts are not backed up together, they should also be backed up in isolation.
Why do you want to encrypt a salt? Salts are normally public information - they only exist to prevent pre-computed "rainbow-table" offline attacks on databases of passwords. I think you need to be clearer about what you are attempting to do and why.
Related
Say I have a database of users (customers). Some of these customers have logged in through a portal, some of them have not and only exist in the database to facilitate customer management by an administrator. At a later date, customers may decide to begin using the portal, at which point they'll need to be provided a password.
Assuming the randomization method is reasonably secure, are there any security implications related to the timing of the salt generation?
ie.: is it better, worse, or irrelevant to be salting all accounts as early as possible vs. salting only at the time a password is created?
The main idea behind the salts, is to offer protection against rainbow tables, which are databases containing pre-hashed passwords. Having each password salted using a different salt allows you to minimize this risk, since now (in theory) there should be no rainbow table containing your password.
As long as you're using a cryptographically secure pseudo-random number generator (CSPRNG) to generate your salts, there should not be a problem with salting your passwords as early as possible (and it'll be even better if you use the salting mechanism already included in most modern implementations). After all, you only care about always producing a different hash. And salts are not even secret values, if your database got compromised, the attacker will already have the hashed password and the salt (they're usually stored like salt$base64HashedPassword, or they just have a column for the salt), and salts are not like the IVs in cipher block chaining (CBC) where an attacker can take advantage of a predictable IV. Here you only care about always producing a different hash, so as long as you do it, everything should be ok.
Edit: Now I'm curious about something. You're talking about salting the password someday in the future... does that mean that you're storing it as plaintext or in a recoverable way before salting it? Because now that'll be a bad practice. You need to salt it as soon as you get it, since you should not know anything about user's passwords.
I have inherited an app to maintain and I just discovered that when a user logs in, the returned JSON from a successfully login contains:
Primary Key of the User record in the DB
User Name
Encrypted Password
The password's Salt
It seems that having the Salt and Encrypted password voids the purpose of the salt in general.
A brute force or lookup table attack is now available again as a cracking approach.
Am I correct on this, and is there more of a threat than just that?
It's not the greatest but it is generally OK to disclose the salt. You're thinking of a pepper, which is to be kept secret.
The salted hash is not meant to prevent a brute force attack. It is meant to prevent a rainbow attack. By including the salt in the input value to the hashing algorithm, it becomes impossible to precompute lookup tables, unless the hacker creates a lookup table for each and every possible salt.
In my opinion, even when it's not something like giving away a password, you're giving away information that your front-end will not need at all and that could lead to an attacker getting the password! I mean, yes, if an attacker gets that information, he still needs an exhaustive search, with all the possible password combinations concatenated with that salt (or hashing a password dictionary with that salt), but you're giving him resources for an offline attack, and now he can try as much different passwords as he wants until he gets bored, or he gets the real password.
Someone may be thinking that it's the same as an attacker trying to authenticate with different passwords, but the main difference, is that in an online attack, you can limit the number of login attempts, so he'll not be able to try as much as he wants, while in an offline attack, he can try as many passwords as he wants.
All this could be avoided by just sending a boolean, instead of the full object and since it's not like it will require a huge refactory or something like that, I think that it's something that needs to be fixed (and you should also take a look at what he does with that information, in the worst case scenario, he's retrieving the password's hash to store it in a cookie or local storage to keep authenticating the user, or something like that).
If the salt & hash is only available from a POST to the login handler, then the damage here is very limited.
If there is some webmethod (/currentUser/getDetails) that returns the data, then this is a risk should their be any Cross-Site Scripting (XSS) vulnerabilities elsewhere on the site. Any attacker could call this method via the XSS, and then retrieve the hashed password and salt for offline cracking.
Another low risk is if the JSON response does not output anti-caching headers then another user of the same computer may be able to retrieve their password hash.
I am more concerned that the password hashes are in Hash(Password+Salt) format, rather than in a format using a secure algorithm such as bcrypt or pbkdf2.
Hybris (version 5.1) can store user passwords in the clear (the default), or using MD5. The MD5 option is not a straight MD5 hash of the password, so i suspect some kind of "salting" is involved. But what? My goal is to be able to write a password reset application that can write new random passwords to the hybris database in MD5 mode (not in the clear).
Getting a little closer: I know that my configuration is using core.saltedMD5PasswordEncoder, and that the value of the salt is set in hybris/bin/platform/ext/core/resources/core-spring.xml
Still, without the source for saltedMD5PasswordEncoder, i may not get very far.
Hybris supports more than one password encoding schema. Which schema or strategy is actually used depends on your configuration.
You will have to look up the documentation for your password encoding strategy to see how the fields are mapped.
Usually a salt is randomly generated for each user and stored together with the password in the same object (database row).
Furthermore MD5 should not be used anymore. It is broken beyond repair and a salt will not fix it.
Please consult the hybris documentation on password encoding https://wiki.hybris.com/display/release5/Password+Storage+Strategies
and stack overflow for password storage best practices.
does using hash functions and algorithims suffice the need to encrypt the data, while communicating with the server
I am applying salt mechanism in my project and I will be concatenating the salt with the entered password, and then hash them all.
do I still need to encrypt the result?
The usual workflow for a website to transmit user passwords looks like this:
The client sends the password plaintext to the server.
The transmission is done with an encrypted connection (HTTPS/SSL), to prevent a ManInTheMiddle attack.
The server calculates a hash of the plaintext password, and this hash is then stored in the database. It is not necessary to encrypt the hash any further.
Make sure you use a random unique salt for each password, and a slow hash function with a cost factor for hashing passwords. Good algorithms are BCrypt, PBKDF2 or SCrypt.
Storing passwords
To store user passwords securely, you need 3 things:
Do not store the plain password, store a hash instead
The hash makes it extremely difficult to recuperate the password even if an attacker manages to capture the entire database
To prevent the use of rainbow tables, you need a salt
The salt is stored in the clear (can be along with the hash) and is random, one for every user and you can easily chose a few one whenever the user changes their password.
You need a SLOW hash, not a fast hash
What are fast hashes: MD5 (consider it broken), SHA-1, SHA-2, ... are unsuitable as the attacker can perform them too fast and use dictionary attacks to try common passwords and find that way up to 95% of you user's passwords in mere hours on modern rigs.
How slow does it need to be ? As slow as you can afford.
And there's a rule 0: Do not invent crypto yourself, you will make serious mistakes before you know it.
Other privacy sensitive info
You're most probably also storing other sensitive information of your visitors in addition to the passwords (email addresses, IP addresses, names, postal address, ...), CC numbers (you better not go there), ...
You need to protect that as well and using hashes isn't the way to do that in most cases. Some of these have requirements and regulations of their own (e.g. Credit Card data is regulated by the issuers who'll force you to be compliant with PCI-DSS).
In essence you need to do a risk analysis and manage that risk by either accepting it ("so be it"), transferring it ("get insurance"), avoid it ("we're not storing that"), or mitigating it ("we're going to improve our way of working").
encryption
Why the media will make you believe there's a "magic" solution in that incomprehensible "encryption" thing, in reality it needs to be done right and in the right conditions to have any meaning at all.
E.g. If you encrypt the entire disk of a server: it will not protect you from an attacker abusing your server scripts and getting to the database (as the database engine and webserver scripts have access to the decrypted disk already)
So, you really need to go back to the risk analysis and chose the measures there instead of getting ahead of yourself and suggesting encryption as a tool that's unlikely to help you for your biggest risks.
In my web application, I'm implementing a blacklist of passwords that user's won't be able to select. As mentioned in Jeff's God Login post, this is because some passwords are very commonly used and exist in readily available wordlists used by brute forcing tools.
I had planned to store the blacklisted passwords in a database table (in the clear), with an MD5 hash of it as a Functional Index. So, when the query is sent to the server, it looks like this:
SELECT 1
FROM blacklist AS a
WHERE MD5(a.password) = 'MD5stringOfPasswordSubmitted';
I don't think the "in the clear" storage of these passwords is an issue since the passwords are blacklisted. No user can set it to one of these.. so who cares if passwords in this table are stored in the clear.
But, is the transmission of this query to the database server a problem I should worry about?
If my user is trying to set their password, at the moment the app will MD5 the password, send that to the database to query this blacklist table. If no result is returned, the app will allow them to have it as their password (as long as other validation requirements are also met).
Is this something I should worry about?
Could this be implemented another way so passwords users are trying to set are kept secure still? Is it really necessary to resort to storing a salted hash via Bcrypt (like is in my user table) even just for this blacklist usage? Would using a YAML file in the local directory structure of my app have any of this same risk?
The aim is to prevent users choosing a password that's common, and checking that in a very fast way (hence MD5) as part of the validation process.
I don't see how the transmission of the query could be a problem. If your web application does the MD5 encoding and an attacker intercepts the communication with the database, there is no way he can get back the user's password from it.
MD5 is not safe for storing passwords as attackers may be able to find passwords that result in the same hash value (collisions), but there is no way to convert a hash value back to the clear text from which it originated.
If you're worried about leaking other sensitive data when querying the database, you could consider encrypting the communication channel.
I wouldn't worry about the transmission of passwords since they are hashed using a one-way algorithm (as user18044 pointed out) however expanding more on the weaknesses of MD5 - I wouldn't use that algorithm at all especially if you aren't using a salt. The reason why is because MD5 rainbow tables have been created for a very large set of possible combinations of passwords. In fact it's very likely that the password lists that you are referring to have been generated after searching MD5 tables or using online services that will give you a password by submitting an MD5 hash (if the password has already been cracked previously or is in some table). I would recommend using a salt or using another algorithm like SHA-256. Security is my specialty and I have a rig that is capable of cracking MD5 hashes at hundreds of billions per second however if there is a salt involved it either slows me down or stops me all together (if the salt is not known). That same rig can crack SHA-256 but it takes much longer for it to crack each one because SHA-256 iterates over itself enough times to make each iteration slow enough to make cracking less feasible.
As was already mentioned I would certainly use SSL either way to better protect all data that is transmitted.
But, is the transmission of this query to the database server a problem I should worry about?
This depends on your network topology. e.g.
Is the database server on the same private local network? Then this is low risk.
Is the database server on the same network, but shared with other machines and users. Then this is medium risk (you need to trust all the other machines and users).
Is the database server across the internet? Then this is high risk.
Depending on your accepted risk level, you may want to protect the connection to the database with SSL/TLS.
Even though you are hashing with MD5, MD5 is considered a weak hashing algorithm so if a MITM grabs the password as it is queried on your database, they could run it through a tool such as John the Ripper using a word list and intercept any password set by your users.
You could try and hash the password using another algorithm for this lookup - however this means implementing a "static salt" (called a pepper) on your system to avoid any hash comparisons of intercepted data. It may be much easier to simply connect with SSL/TLS to avoid this completely.
For storage of the password itself (once it has passed your check), definitely use a secure algorithm here such as bcrypt or scrypt.