如何使用Java中的OID获取哈希算法名称?

我试图在Java中计算字节数组的哈希值。 要获取MessageDigest实例,我需要通知哈希名称,但我只有哈希OID。 是否有另一种方法可以执行此操作或从哈希OID到哈希名称的现有映射?

String oid = "1.2.3.4.5"; String digestAlgorithmName = getDigestAlgorithmName(oid); MessageDigest messageDigest = MessageDigest.getInstance(digestAlgorithmName); byte[] actualHash = messageDigest.digest(new byte[] { 0x00 }); 

大多数安全提供程序(以及BouncyCastle就是其中之一)不仅定义了单个算法名称,还定义了包含OID的别名。 因此,可以将OID直接传递给JCA,如下所示:

 String oid = "1.3.14.3.2.26"; MessageDigest md = MessageDigest.getInstance( oid, BouncyCastleProvider.PROVIDER_NAME); String digestAlgorithmName = md.getAlgorithm(); 

digestAlgorithmName将等于SHA-1 。 这不适用于SUN安全提供程序。

我找到了答案。 来自Bouncy Castle Library的 org.bouncycastle.cms.CMSSignedHelper类具有映射。 我从那里提取了所需的片段并复制到这里。

 ... 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); } } 

org.bouncycastle.cms.CMSSignedGenerator类具有每个支持的算法的常量。 它的常量是公共的,因此它们比仅包可访问的CMSSignedHelper更容易使用。