...
Code Block | ||
---|---|---|
| ||
public final class Password { private void setPassword(byte[] pass) throws Exception { bytes[] encrypted = encrypt(pass); // arbitrary encryption scheme clearArray(pass); saveBytes(encrypted,"password.bin"); // encrypted password to password.bin } private boolean checkPassword(byte[] pass) throws Exception { boolean arrays_equal; byte[] encrypted = loadBytes("password.bin"); // 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) { for (int i = 0; i //set all of the elements in a to zero< a.length; i++) { a[i] = 0; } } } |
An attacker could potentially decrypt this file to discover the password. The attacker could be someone who 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 Password { private void setPassword(byte[] pass) throws Exception { byte[] salt = generateSalt(12); 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(salt, "salt.bin"); saveBytes(hashVal,"password.bin"); // save the hash value to password.bin } private boolean checkPassword(byte[] pass) throws Exception { byte[] salt = loadBytes("salt.bin"); 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("password.bin"); // load the hash value stored in password.bin return Arrays.equals(hashVal1, hashVal2); } private byte[] generateSalt(int n) { // Generate a random byte array of length n } private byte[] appendArrays(byte[] a, byte[] b) { // Return a new array of a appended to b } private void clearArray(byte[] a) { // set all of the elements in a to zero for (int i = 0; i < a.length; i++) { a[i] = 0; } } } |
In both the setPassword()
and checkPassword()
methods, the cleartext representation of the password is erased immediately after it is converted into a hash value. Consequently, attackers must work much harder to retrieve the cleartext password after the erasure. Providing truly guaranteed erasure is extremely challenging, likely to be platform-specific and may even be impossible because of the involvement of copying garbage collectors, dynamic paging, and other platform features that operate below the level of the Java Language. Note, however, that most other languages share these complications (with the exception of garbage collection).
...