Reputation: 1714
In our project we create a SHA1 hash using following OpenSSL functions,
SHA_CTX ctx;
SHA1_Init (&ctx);
SHA1_Update (&ctx, value, size);
SHA1_Final (returned_hash, &ctx);
We are using a key and SHA1_Update is called multiple times.
I have to verify that hash using Java. I have written following functions,
public static Mac hmacSha1Init(String key) {
Mac mac = null;
try {
// Get an hmac_sha1 key from the raw key bytes
byte[] keyBytes = key.getBytes();
SecretKeySpec signingKey = new SecretKeySpec(keyBytes, "HmacSHA1");
// Get an hmac_sha1 Mac instance and initialize with the signing key
mac = Mac.getInstance("HmacSHA1");
mac.init(signingKey);
} catch (Exception e) {
throw new RuntimeException(e);
}
return mac;
}
public static Mac hmacSha1Update(String value, Mac mac) {
try {
// update hmac with value
mac.update(value.getBytes());
} catch (Exception e) {
throw new RuntimeException(e);
}
return mac;
}
public static String hmacSha1Final( Mac mac) {
try {
// Compute the hmac on input data bytes
byte[] rawHmac = mac.doFinal();
return Base64.encodeBase64String(rawHmac);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
I am using the hmacSha1Init with the key and update multiple times with the Mac and finally call hmacSha1Final with the mac.
Ex.
Mac mac = hmacSha1Init("ssdsdsdioj298932276302392pdsdsfsdfs");
mac = hmacSha1Update("value1", mac);
mac = hmacSha1Update("value2", mac);
mac = hmacSha1Update("value3"', mac);
String hash = hmacSha1Final(mac);
But I do not get same SHA1 hash generated via OpenSSL. There is very limited documentation on the web. Can someone please direct me
Upvotes: 1
Views: 1948
Reputation: 1453
The reason for the two hashes to be different is that the input used in the openssl SHA1 algorithm is different that the one is used in Java framework. If you use the MD5 algorithm you will see that the result is the same. In this case openssl uses the same.
What changes? Well, openssl considered SHA1 not safe enough, fine, so they decided to give it another turn. Normally (MD5 and Java framework), take the input string and generate an ASN1 DER encoding of it. Then they take it and pass it to the algorithm. For SHA1 openssl is doing a normalization before generating the ASN1 DER encoding. It is calculating the CANONICAL format of the input, then generating the ASN1 DER and then passing it to the algorithm.
You will have to modify the Java framework to get the same results. I am trying to do it myself too :)
Here you can find a post about it in the openssl distribution list: http://openssl.6102.n7.nabble.com/The-new-subject-hash-algorithm-td44844.html
And here an implementation from the ICM Uniwersytet Warszawski. Not sure how reliable it is, that's why I am trying myself.
Upvotes: 1