I am trying to compute the hash of a byte array in Java. To get a MessageDigest instance, I need to inform the hash name, but I only have the hash OID. Is there another way to do this or an existing map from hash OID to hash names?
String oid = "1.2.3.4.5";
String digestAlgorithmName = getDigestAlgorithmName(oid);
MessageDigest messageDigest = MessageDigest.getInstance(digestAlgorithmName);
byte[] actualHash = messageDigest.digest(new byte[] { 0x00 });
I found an answer. The class org.bouncycastle.cms.CMSSignedHelper from Bouncy Castle Library has the mapping. I extracted the required snippet from there and copied here.
...
private static final Map encryptionAlgs = new HashMap();
private static final Map digestAlgs = new HashMap();
static
{
encryptionAlgs.put(X9ObjectIdentifiers.id_dsa_with_sha1.getId(), "DSA");
encryptionAlgs.put(X9ObjectIdentifiers.id_dsa.getId(), "DSA");
encryptionAlgs.put(OIWObjectIdentifiers.dsaWithSHA1.getId(), "DSA");
encryptionAlgs.put(PKCSObjectIdentifiers.rsaEncryption.getId(), "RSA");
encryptionAlgs.put(PKCSObjectIdentifiers.sha1WithRSAEncryption.getId(), "RSA");
encryptionAlgs.put(TeleTrusTObjectIdentifiers.teleTrusTRSAsignatureAlgorithm, "RSA");
encryptionAlgs.put(X509ObjectIdentifiers.id_ea_rsa.getId(), "RSA");
encryptionAlgs.put(CMSSignedDataGenerator.ENCRYPTION_ECDSA, "ECDSA");
encryptionAlgs.put(X9ObjectIdentifiers.ecdsa_with_SHA2.getId(), "ECDSA");
encryptionAlgs.put(X9ObjectIdentifiers.ecdsa_with_SHA224.getId(), "ECDSA");
encryptionAlgs.put(X9ObjectIdentifiers.ecdsa_with_SHA256.getId(), "ECDSA");
encryptionAlgs.put(X9ObjectIdentifiers.ecdsa_with_SHA384.getId(), "ECDSA");
encryptionAlgs.put(X9ObjectIdentifiers.ecdsa_with_SHA512.getId(), "ECDSA");
encryptionAlgs.put(CMSSignedDataGenerator.ENCRYPTION_RSA_PSS, "RSAandMGF1");
encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3410_94.getId(), "GOST3410");
encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3410_2001.getId(), "ECGOST3410");
encryptionAlgs.put("1.3.6.1.4.1.5849.1.6.2", "ECGOST3410");
encryptionAlgs.put("1.3.6.1.4.1.5849.1.1.5", "GOST3410");
digestAlgs.put(PKCSObjectIdentifiers.md5.getId(), "MD5");
digestAlgs.put(OIWObjectIdentifiers.idSHA1.getId(), "SHA1");
digestAlgs.put(NISTObjectIdentifiers.id_sha224.getId(), "SHA224");
digestAlgs.put(NISTObjectIdentifiers.id_sha256.getId(), "SHA256");
digestAlgs.put(NISTObjectIdentifiers.id_sha384.getId(), "SHA384");
digestAlgs.put(NISTObjectIdentifiers.id_sha512.getId(), "SHA512");
digestAlgs.put(PKCSObjectIdentifiers.sha1WithRSAEncryption.getId(), "SHA1");
digestAlgs.put(PKCSObjectIdentifiers.sha224WithRSAEncryption.getId(), "SHA224");
digestAlgs.put(PKCSObjectIdentifiers.sha256WithRSAEncryption.getId(), "SHA256");
digestAlgs.put(PKCSObjectIdentifiers.sha384WithRSAEncryption.getId(), "SHA384");
digestAlgs.put(PKCSObjectIdentifiers.sha512WithRSAEncryption.getId(), "SHA512");
digestAlgs.put(TeleTrusTObjectIdentifiers.ripemd128.getId(), "RIPEMD128");
digestAlgs.put(TeleTrusTObjectIdentifiers.ripemd160.getId(), "RIPEMD160");
digestAlgs.put(TeleTrusTObjectIdentifiers.ripemd256.getId(), "RIPEMD256");
digestAlgs.put(CryptoProObjectIdentifiers.gostR3411.getId(), "GOST3411");
digestAlgs.put("1.3.6.1.4.1.5849.1.2.1", "GOST3411");
}
String getDigestAlgName(String digestAlgOID) {
String algName = (String)digestAlgs.get(digestAlgOID);
if (algName != null)
{
return algName;
}
return digestAlgOID;
}
String getEncryptionAlgName(String encryptionAlgOID) {
String algName = (String)encryptionAlgs.get(encryptionAlgOID);
if (algName != null)
{
return algName;
}
return encryptionAlgOID;
}
MessageDigest getDigestInstance(String algorithm, String provider)
throws NoSuchProviderException, NoSuchAlgorithmException {
if (provider != null)
{
try
{
return MessageDigest.getInstance(algorithm, provider);
}
catch (NoSuchAlgorithmException e)
{
return MessageDigest.getInstance(algorithm); // try rolling back
}
}
else
{
return MessageDigest.getInstance(algorithm);
}
}
Most of security providers (and BouncyCastle is one of them) defines not only single algorithm name, but also aliases, which include OID. Thus, it's possible to pass OID directly to JCA like this:
String oid = "1.3.14.3.2.26";
MessageDigest md = MessageDigest.getInstance(
oid, BouncyCastleProvider.PROVIDER_NAME);
String digestAlgorithmName = md.getAlgorithm();
digestAlgorithmName
will be equal to SHA-1
in the end. This doesn't work with SUN security provider.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With