I use NHibernate and have a custom type for encrypting passwords in the database so that I can use string properties to represent passwords, but NHibernate transforms / encrypts the value before storing in the db. Currently, I store a salt value and an encryption key in the config file, but I'd really rather move to a password hash. However, the custom NHibernate type knows nothing about the object being stored other than the value of the property it is being told to handle, so I can't generate some random salt and store it with the object in another property from within this custom type.
Since I can't store the salt separately, I wonder if it would be OK to derive the salt from the password itself, and then hash the combination of the two. For example, I might take the password, MD5 hash it, then use the MD5 hash as the salt. Would this be OK? This would allow me to persist the password in a deterministic manner while using a unique (but derived) salt value per password, but are there any security considerations when doing it this way?
EDIT:
Because all of the answers I've received so far have failed to account for the context of the question, let me present the signature of the method defined in NHibernate terms.
public override void Set(IDbCommand cmd, object value, int index)
{
var param = (IDataParameter)cmd.Parameters[index];
if (value == null)
{
param.Value = null;
}
else
{
var temp = value.ToString();
var encrypted = encryptor.Encrypt(temp);
param.Value = encrypted;
}
}
That's all NHibernate gives me. I receive the IDbCommand object, a value, and a parameter index. I know nothing about the parameters themselves or the type of object being persisted. I only have a value. I cannot generate a random salt and store it in a separate property, because I do not know what properties exist on the object being persisted, nor which order they are stored in the parameter collection. My goal is to hash the password in the most secure way possible within the context of this method call. If you're going to argue against my suggestion, it would be helpful to receive an alternative idea within this context.
No! If you derive salt from the password all the same password have the same hash and the salt became useless.
Try with
var temp = value.ToString();
var salt = generateRandonSalt();
var encrypted = encryptor.Encrypt(temp + salt);
param.Value = salt + encrypted;
With "+" I mean a concatenation operand or something compatible with your value. And naturally you need to know always the salt length so you can check password next times.
The purpose of a hashing function is to derive something from the password. If you derive the salt from the password, then that derivation is effectively part of your hashing function. You've just altered/augmented the hashing function, and do not actually have a salt.
Salts have to be random.
Their job is to make it harder to brute-force a password. If a salt has 65536 different values (for example) then it means that the same password can hash 65536 different ways. If someone wants to build a dictionary which reverses hashes back to passwords, his dictionary will require 65536 entries for just one password.
The salt must have nothing to do with the password for this idea to work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With