I have written, previously in Python, a function to garble a target string using PBKDF2:
from hashlib import pbkdf2_hmac
from binascii import hexlify
def garbleString(string, salt, iterations, hash_algorithm):
target = str.encode(string)
dk = pbkdf2_hmac(hash_algorithm, target, salt, iterations)
hash = hexlify(dk)
return (hash, salt, iterations)
>>> garbleString("1000000000","salt",100000,'sha256')
('d973f4855206bd777b25355782f1b14bf06fb395bf49a26086035b3b8820a74b', 'salt', 100000)
Based on this page, this function is correct -- it yields the same hash for the same inputs. http://www.neurotechnics.com/tools/pbkdf2
I am now trying to implement the same in Java, here is where I am now:
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.xml.bind.DatatypeConverter;
public class GarbledStringFactory {
private String algorithm;
public GarbledStringFactory(String algorithm){
this.algorithm = algorithm;
}
public String getGarbledString(String string, String salt, int iterations, int derivedKeyLength) throws NoSuchAlgorithmException, InvalidKeySpecException {
SecretKeyFactory f = SecretKeyFactory.getInstance(this.algorithm);
KeySpec spec = new PBEKeySpec(string.toCharArray(), salt.getBytes(), iterations, derivedKeyLength * 8);
SecretKey key = f.generateSecret(spec);
String hexStr = DatatypeConverter.printHexBinary(key.getEncoded());
return hexStr;
}
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException {
// TODO Auto-generated method stub
GarbledStringFactory factory = new GarbledStringFactory("PBKDF2WithHmacSHA256");
String hash = factory.getGarbledString("1000000000","salt",100000,32);
System.out.println(hash);
}
}
This yields the hash "D973F4855206BD777B25355782F1B14BF06FB395BF49A26086035B3B8820A74B", which is the same, just with different letter casing. Does the casing matter?
No, the casing doesn't matter.
If you inspect the hashes you'll find that the only letters included are from A to F. This isn't really a string, but rather a hexadecimal (base 16) number equivalent to 98356763175438224738455306401383784358747884932620687880657531803811513935691 in decimal / base 10.
It doesn't matter whether the digits are shown in upper- or lower-case. The meaning is the same.
You can see this in the Python interpreter, where a leading 0x
indicates a hexadecimal number:
>>> hex(12)
'0xc'
>>> 0xf
15
>>> 0xF
15