SHA algorithm generates each time unique hash string for a same key

前端 未结 1 1621
青春惊慌失措
青春惊慌失措 2021-02-11 04:13

I know there are lots lots of articles available about hashing and encryption algorithm.

I have figure it out from them that use hashing function instead of encryption <

相关标签:
1条回答
  • 2021-02-11 04:33

    This is your most immediate problem:

    byte pass[] = md.digest();
    System.out.println(pass.toString());
    

    You're not returning the hash of the string. You're returning the result of calling toString() on a byte[]. Arrays in Java don't override toString(), so you get the default implementation, which has everything to do with the identity of the object and nothing to do with the data in the byte array:

    The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `@', and the unsigned hexadecimal representation of the hash code of the object.

    (Arrays don't override hashCode() either, so that's obtained from the default implementation in Object too...)

    Basically, you need a different way of converting a byte[] to a String... or store the byte array directly in the database, of course. If you do want to convert to a string, I suggest you use either hex or base64. For base64, I'd suggest the iharder.net public domain library... or if you're using Java 8, you can use java.util.Base64. (It's astonishing that it took so long to get a base64 class into the standard libraries in a context other than XML etc, but there we go.)

    return Base64.getEncoder().encodeToString(md.digest());
    

    Your code has an additional problem though:

    md.update(clearTextPassword.getBytes());
    

    This uses the platform default encoding to convert the password into a byte array. That's not a good idea - it means you could end up getting different hashes based on what system your code is running on. It's better to specify the encoding explicitly:

    md.update(clearTextPassword.getBytes(StandardCharsets.UTF_8));
    

    Additionally, catching an exception if SHA-256 is missing, logging and continuing with a blank string is almost certainly the wrong approach. Do you really want to populate your database with empty strings, allowing anyone to log in with any password? If your system is in that state, the best thing you can do is almost certainly to fail any request to do anything with passwords. You probably want to convert the NoSuchAlgorithmException into some sort of RuntimeException and rethrow.

    Finally, storing a simple SHA-256 hash probably isn't a good idea anyway.

    • You probably want an HMAC instead
    • You should at least use a random salt to avoid the same passwords having the same values in the database. (Otherwise, an attacker can use that information to their advantage.)

    I'm far from an expert on security, so I won't advise you much further on the right way to do things - but I would actually suggest trying to find a well-respected library written by security experts rather than trying to implement this yourself. Security it very hard to do right.

    0 讨论(0)
提交回复
热议问题