Storing passwords or any sensitive information securely is a critical aspect in any application. In this post, I am going to talk about various approaches to store the passwords, and the pros and cons in each approach.
Hash the passwords
Use one-way hash algorithms to convert the given password into a fixed length of string.
Collision resistance
One way hash algorithms are designed in such a way that it is very difficult to find two different inputs that produce the same hash value.
What are the popular one-way hash algorithms?
some popular one-way hash algorithms include:
a. SHA-2 (Secure Hash Algorithm 2)
b. MD5 (Message Digest 5)
c. RIPEMD-160 (RACE Integrity Primitives Evaluation Message Digest)
d. BLAKE2
Following snippet generate a hash using SHA-256 algorithm
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(string.getBytes());
Find the complete working application below.
HashGenerationDemo.java
package com.sample.app;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class HashGenerationDemo {
public static String generateSHA2Hash(String string) throws NoSuchAlgorithmException {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(string.getBytes());
return toHexString(hash);
}
private static String toHexString(byte[] hash) {
StringBuilder hexString = new StringBuilder();
for (byte b : hash) {
hexString.append(String.format("%02x", b));
}
return hexString.toString();
}
public static void main(String[] args) throws NoSuchAlgorithmException {
String message = "This is message is very sensitive and should be transferred securily";
String hash = generateSHA2Hash(message);
System.out.printf("Original message : %s\n", message);
System.out.printf("Hash : %s", hash);
}
}
Output
Original message : This is message is very sensitive and should be transferred securily Hash : 129a200ca934a67d74d68ba04977151f3c2ad5cfac1f92d4a5675ba93a6855ad
Drawback of this approach
Rainbow table attacks: Attacker can create pre-computed tables of hash values for common passwords, and can then use this dictionary to generate collisions, which can be used to crack other passwords.
How to address this problem?
We can solve this problem by salting the password.
Salting the password
Salting the password makes the attacker task much more difficult to crack passwords using rainbow table attacks and collision attacks.
In this procedure, you generate a random text/value and add it to the actual password before hashing it.
hashedValue = hash(password+random_value)
Scenario 1: User 'A' register with username and password
When a person 'A' registers your website with the username and password. You are going to generate a random text/value, add it to the password and compute the hash. Your table looks like below.
id |
username |
salt |
hased_password |
|
|
|
|
|
|
Scenario 2: What if two different users registered with same password.
As the salt value generated for the two users is different, our application generates two different hashed passwords. You can confirm the same from below application.
HashGenerationUsingSalt.java
package com.sample.app;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
public class HashGenerationUsingSalt {
public static String generateSalt() {
SecureRandom random = new SecureRandom();
byte[] salt = new
byte[32];
random.nextBytes(salt);
return new String(salt, StandardCharsets.UTF_8);
}
public static String generateSHA2Hash(final String password) throws NoSuchAlgorithmException {
String salt = generateSalt();
String saltedPassword = password + salt;
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(saltedPassword.getBytes());
return toHexString(hash);
}
private static String toHexString(byte[] hash) {
StringBuilder hexString = new StringBuilder();
for (byte b : hash) {
hexString.append(String.format("%02x", b));
}
return hexString.toString();
}
public static void main(String[] args) throws NoSuchAlgorithmException {
String password = "password@334GT123";
int count = 10;
System.out.printf("Experiment by generating hash for the same password %d times\n", count);
for (int i = 0; i < count; i++) {
String hash = generateSHA2Hash(password);
System.out.printf("%d. Generated hash : %s\n", i, hash);
}
}
}
Output
Experiment by generating hash for the same password 10 times 0. Generated hash : d0e9e10d549df962f06b6c810612a3639bff3949639a370dcf1a8ecc68f1c1d8 1. Generated hash : 7dfdb5815ba7c06258f9added188cc1ab918eeab9c2cf511ca9a86720042ce96 2. Generated hash : a9c3151cf5885c16f0e127cf0e444275a3e486fce47767b08ca11eb2733de69c 3. Generated hash : 02f9dbebde4e20fcd5b9b283ba51fcdc60e242a087c72475a8f24d5d7ae301d5 4. Generated hash : 3780aebc82a37eecb321875e8480f4a98717ccad8a203118780e6bbe4b381a4b 5. Generated hash : 6a1fbc126321b0ac14f2074f13b5b83dc43c72b08acf04872896c91c3ced6b75 6. Generated hash : 0d44d7e2add6c7233de8f735f6374c46bf1827db0f6c6c59f356fb1333fc15e0 7. Generated hash : 3deeaac8f2ab8297333458592eb9ca02c40e9a6fda4289dcf349e523bff96f7b 8. Generated hash : 52588d3fd5ea7c319faa7fdf98ac7ec4e2a04b5bf4ae78e802d0a0788a389a9a 9. Generated hash : a6f2c3d22b6b40ae006496d23fc6a3d1608c51cc5ac35cf97f7da88e3325cef2
References
How to generate SHA-1 hash of a file?
No comments:
Post a Comment