That would be good practice?
No. The recommended way to protect a password is through a slow hash (PBKDF2, Bcrypt or scrypt). You’re right to say that a fast hash is ineffective, but you realize that using an encryption algorithm in a single direction (just cipher, never decrypt) is almost the same as applying a hash?
It would not be honest of me to say that your technique is at all useless, however - if an attacker gets access to the database and only to the database (for example, exploiting an SQL Injection) it will be unable to recover passwords. In fact, there is a technique called "Pepper" (pepper) that takes advantage of this fact to give additional protection to a hash (more details in the answer to the linked question). The problem lies in basing all your security only on this premise (that the attacker will not have access to your code, even if only for reading).
AES would be the best algorithm?
Neither AES nor any other symmetric encryption algorithm (such as 3DES, etc). For even if you Do not intend to decipher the password at any time, an attacker who gets access to your BD and your key will not do the same "as a matter of honor", it will undo the encryption and that’s it! That is, your login is slow (because you keep encrypting and comparing) and the attacker continues fast...
An asymmetric cipher would be marginally better (so the attacker could not simply decipher, he would have to password test - because if the private key is off the server, he can only use the public key) but she still runs the risk of being overly quick about a hash. Ultimately, a hash is even the best you can reasonably achieve, and the use of a Pepper would help give the additional security you sought when proposing this method (although I personally don’t usually worry too much about it - it will depend on how sensitive your particular application is).
How could it be done the AES encryption a slow hash using C#? There is already some ready method?
The Rfc2898DeriveBytes
is a native solution for PBKDF2 (there are also implementations Bcrypt and scrypt for .Net, third party I believe), you just need to adjust the parameters accordingly. An example would be:
string pwd = senha_a_ser_hasheada;
// Cria um sal aleatório de 64 bits
byte[] salt = new byte[8];
using (RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider())
{
// Enche o array com um valor aleatório
rngCsp.GetBytes(salt);
}
// Escolha o valor mais alto que seja "tolerável"
// 100 000 era um valor razoável em 2011, não sei se é suficiente hoje
int myIterations = 100000;
try
{
Rfc2898DeriveBytes k = new Rfc2898DeriveBytes(pwd, salt, myIterations);
byte[] hash = k.getBytes(32);
// Codifica esse hash de alguma forma e salva no BD
// (lembre-se de salvar o salt também! você precisará dele para comparação)
If you want to use one Pepper, take the secret value that only exists in your code (or in some configuration file) and attach it to the password or salt before hashing (adjusting the size if necessary).
http://answall.com/q/2402/101
– Maniero
I gave two answers here. I don’t know if this is a case of replying, but if you need me, just say the word.
– Leonel Sanches da Silva
Look at the question the mustache quoted. Using AES to protect passwords is tricky because if an attacker gains access to your server he also gains access to the symmetric encryption key... An asymmetrical encryption improves things a bit (since you will never "reverse", you can keep the private key off the server), but still has drawbacks compared to a slow hash.
– mgibsonbr