-1

I have a utility class with a method responsible for encrypting the user password. This is the method:

public static String encryptPassword(String password) {
    MessageDigest md = null;

    try {
        md = getInstance("sha-512");
    } catch (NoSuchAlgorithmException ex) {
        Logger.getLogger(PasswordUtils.class.getName()).log(Level.SEVERE, null, ex);
        throw new IllegalArgumentException();
    }

    md.update(password.getBytes());
    return Base64.getEncoder().encodeToString(md.digest());
}

I'm using MySQL to persist my data and I want to persist the password as a VARCHAR. To get an idea of the needed length I made some research and found this post and this one who talk about a needed length of 128. I tested the method manually with severals strings and the String.length() method of the hashed strings gives me a fixed length of 88. Also I saw an example project and uses 'VARCHAR(100)' to store the password.

What is the optimal size of the VARCHAR for this algorithm? Thanks in advance for your answers.

Community
  • 1
  • 1
Alvaro Pedraza
  • 1,176
  • 6
  • 20
  • 44
  • You should use the MySQL functions for this, not Java code. Don't keep a dog and bark yourself. – user207421 Jun 08 '16 at 21:01
  • It was an option but I decided to implement all business logic in the Service Layer (Java) and not in the Data Access Layer (MySQL). I'll take note of your comments and the answers for a future improvement of the system. – Alvaro Pedraza Jun 08 '16 at 23:03
  • This is not 'business logic'. It is database logic. – user207421 Jun 20 '16 at 05:04
  • Indeed, when you store the password it's database logic, but when you sign in to the system you need to encrypt the password typed by the user and compare it with the stored one, and that's business logic. As I said, I'll take it into account for future improvement, security isn't a critical issue in my system at the moment – Alvaro Pedraza Jun 20 '16 at 15:37

2 Answers2

1

The length of the sha512 hash is 512bit = 64byte/chars. So if you would just store the plain hash as a binary field in MySQL, you need exactly 64 byte.

If you store them with base64, you need 88 chars: base64 can only store 6 bit of information per character, not 8 bit that a normal character has. So you need 512bit / 6bit per char = 85,3bit. Base64 has some padding rules, it must always pad the data with zeros until the bit count is a multiple of 6, so it is padded to 528bit / 6bit = 88bit. That is the fixed number you need.

Aside from that, it is never a good idea to store passwords that are simply hashed. They can be easily reversed by rainbow table attacks. I am sure there is some Linux crypt() compatible java function that uses a salt and several thousand rounds to prevent rainbow table attacks.

Dennis B.
  • 1,567
  • 1
  • 13
  • 20
  • In **no instance** is a hash acceptable, at a minimum it needs to be an HMAC with a random seed. – zaph Jun 08 '16 at 20:55
  • But HMAC has absolutely nothing to do with secure password hashing. HMAC uses a cryptographically secured hash so you can detect tampering with encrypted data. – Dennis B. Jun 08 '16 at 20:58
  • Who would purposely want to weaken security? I, because I do not agree with you that HMAC is needed for secure password hashing? The HMAC does not provide any additional security over a salted password with enough rounds to achieve a certain workload factor. That is exactly what e.g. bcrypt does. And bcrypt does NOT use a HMAC because a HMAC is to secure your encrypted texts against tampering and not to produce hashes. PBKDF2 is something completely different. That is to derive a password from a secret key. So please get your crypto vocabulary in order before arguing... – Dennis B. Jun 08 '16 at 21:46
  • Three letters: FBI, three more: TSA, then we get to attackers and foreign governments, add forums such as SO which are prime vectors for providing insecure information. The NSA does plant bad cryptographic advice, this is well known in the cryptographic community. Heck the US congress was considering passing a backdoor law. Please explain a "salted password" in detail, bcrypt is indeed a secure and good choice for creating a password hash but is not part of your answer. PBKDF2 and password_hash are also good choices. SHA-* by itself is not a secure choice and should not be used. – zaph Jun 09 '16 at 22:49
  • For information on password attacks see [Infosec](http://resources.infosecinstitute.com/10-popular-password-cracking-tools/), [How I became a password cracker](http://arstechnica.com/security/2013/03/how-i-became-a-password-cracker/3/) and [SecLists](https://github.com/danielmiessler/SecLists/tree/master/Passwords). This should convince anyone that just hash protected passwords provided essentially no security. – zaph Jun 09 '16 at 22:50
  • As an example from the [LinkedIn Breach](http://thehackernews.com/2016/05/linkedin-account-hack.html): Since the passwords have been initially encrypted with the SHA1 algorithm, with "no salt," it just took '*LeakedSource*', the paid search engine for hacked data, [72 hours to crack](https://www.leakedsource.com/blog/linkedin) roughly 90% of the passwords. There were 117 Million LinkedIn users. – zaph Jun 10 '16 at 14:27
  • See OWASP [Password Storage Cheat Sheet](https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet#Leverage_an_adaptive_one-way_function) suggested use of PBKDF2. – zaph Jun 20 '16 at 04:47
  • See [How to securely hash passwords, The Theory](http://security.stackexchange.com/questions/211/how-to-securely-hash-passwords/31846#31846) with 600+ up votes on Security StackExchange. Note that PBKDF2 is the first suggestion in "Good Password Hashing Functions" – zaph Jun 27 '16 at 23:00
  • From [DRAFT NIST Special Publication 800-63B Digital Authentication Guideline](https://pages.nist.gov/800-63-3/sp800-63b.html): "*Secrets SHALL be hashed with a salt value using an approved hash function such as **PBKDF2** as described in [SP800-132].*" – zaph Aug 23 '16 at 19:11
-1
  1. SHA-512 as well as all hash function are not encryption.

  2. Simply hashing a password is insufficient and not secure, they are subject to a rainbow table attack. At a minimum an HMAC with a random salt is required but we can and should do better.

Use a function such as Bcrypt, password_hash, PBKDF2 and similar that use an HMAC and iterate such that the function takes around 100ms, the work factor.

See OWASP (Open Web Application Security Project) Password Storage Cheat Sheet.

See How to securely hash passwords, The Theory on Security StackExchange.

This only needs to be done if you want the passwords to be secure—which you should, your users expect.

From DRAFT NIST Special Publication 800-63B Digital Authentication Guideline:

"Verifiers SHALL store memorized secrets in a form that is resistant to offline attacks. Secrets SHALL be hashed with a salt value using an approved hash function such as PBKDF2 as described in [SP800-132]. The salt value SHALL be a 32 bit (or longer) random value generated by an approved random number generator and is stored along with the hash result. At least 10,000 iterations of the hash function SHOULD be performed."

Community
  • 1
  • 1
zaph
  • 111,848
  • 21
  • 189
  • 228