我正在尝试用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 });
答案 0 :(得分:3)
大多数安全提供程序(以及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安全提供程序。
答案 1 :(得分:1)
我找到了答案。来自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);
}
}
答案 2 :(得分:1)
类org.bouncycastle.cms.CMSSignedGenerator具有每个支持的算法的常量。它的常量是公共的,因此它们比只能访问包的CMSSignedHelper更容易使用。