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

Dav*_*eis 7 java cryptography

我试图在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 });
Run Code Online (Sandbox Code Playgroud)

Dav*_*eis 5

我找到了答案。Bouncy Castle 库中的 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);
    }
}
Run Code Online (Sandbox Code Playgroud)


div*_*nov 5

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

String oid = "1.3.14.3.2.26";
MessageDigest md = MessageDigest.getInstance(
    oid, BouncyCastleProvider.PROVIDER_NAME);
String digestAlgorithmName = md.getAlgorithm();
Run Code Online (Sandbox Code Playgroud)

digestAlgorithmNameSHA-1最终将等于。这不适用于 SUN 安全提供程序。