...
It is also important that you append a salt to the password you are hashing. A salt is a randomly generated piece of data that is randomly generated during the creation of the program (and consistent throughout the rest of its implementation) not sure what period of time does this refer to? stored along with the hash value. The use of a salt helps prevents dictionary attacks against the hash value, provided the salt is long enough what is long enough . Each password should have its own salt associated with it. If a single salt were used for more than one passwords, two users would be able to see if their passwords are the same.
Noncompliant Code Example
This noncompliant code example encrypts and decrypts the password stored in credentials.txt
. it needs to be clearer that the issue here is that the program stores encrypted passwords to begin with pw.
Code Block | ||
---|---|---|
| ||
public final class Password { publicprivate static void mainsetPassword(Stringbyte[] argspass) throws IOExceptionException { Â charbytes[] passwordencrypted = new char[100]; BufferedReader br = new BufferedReader(new InputStreamReader( new FileInputStream("credentials.txt"))); // Reads the password into the char array, returns the number of bytes read int n = br.read(password); // Decrypt password, perform operations for (int i = n - 1; i >= 0; i--) { // Manually clear out the password immediately after use password[i] = 0; } br.close();encrypt(pass); //arbitrary encryption scheme clearArray(pass); Â Â saveBytes(encrypted,"credentials.pw"); //encrypted password to credentials.pw } private boolean checkPassword(byte[] pass) throws Exception { boolean arrays_equal; byte[] encrypted = loadBytes("credentials.pw"); //load the encrypted password byte[] decrypted = decrypt(encrypted); arrays_equal = Arrays.equal(decrypted, pass); clearArray(decrypted); clearArray(pass); return arrays_equal; } private clearArray(byte[] a) { //set all of the elements in a to zero } } |
An attacker could potentially decrypt this file to discover the password. This attacker could be someone knows or has figured out the encryption scheme being used by the program.
...
Code Block | ||
---|---|---|
| ||
import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public final class HashExamplesPassword { private String salt = "ia0942980234241sadfaewvo32"; //Randomly generated private void setPassword(String pass) throws Exception { MessageDigest sha_1 = MessageDigest.getInstance("SHA-1"); byte[] hashVal = sha_1.digest((pass+salt).getBytes()); //encode the string and salt saveBytes(hashVal,"credentials.pw"); //save the hash value to credentials.pw } private boolean checkPassword(String pass) throws Exception { MessageDigest sha_1 = MessageDigest.getInstance("SHA-1"); byte[] hashVal1 = sha_1.digest((pass+salt).getBytes()); //encode the string and salt byte[] hashVal2 = loadBytes("credentials.pw"); //load the hash value stored in credentials.pw return Arrays.equals(hashVal1, hashVal2); } } |
...
Code Block | ||
---|---|---|
| ||
import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public final class HashExamplesPassword { private byte[] salt = "ia0942980234241sadfaewvo32".getBytes(); //Randomly generated private void setPassword(byte[] pass) throws Exception { byte[] input = appendArrays(pass, salt); MessageDigest sha_1 = MessageDigest.getInstance("SHA-1"); byte[] hashVal = sha_1.digest(input); //encode the string and salt  clearArray(pass);  clearArray(input);  saveBytes(hashVal,"credentials.pw"); //save the hash value to credentials.pw } private boolean checkPassword(byte[] pass) throws Exception { byte[] input = appendArrays(pass, salt); MessageDigest sha_1 = MessageDigest.getInstance("SHA-1"); byte[] hashVal1 = sha_1.digest(input); //encode the string and salt clearArray(pass); clearArray(input); byte[] hashVal2 = loadBytes("credentials.pw"); //load the hash value stored in credentials.pw return Arrays.equals(hashVal1, hashVal2); } private appendArrays(byte[] a, byte[] b) { //Return a new array of a appended to b } private clearArray(byte[] a) { //set all of the elements in a to zero } } |
...