Как получить имя алгоритма хеширования с помощью OID в Java?

Я пытаюсь вычислить хэш массива байтов в 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 });

person David Reis    schedule 04.09.2009    source источник
comment
Что это за OID? АСН.1? Кто отвечает за эти OID?   -  person Dirk    schedule 04.09.2009
comment
Это OID ASN.1. Эти OID стандартизированы.   -  person David Reis    schedule 04.09.2009


Ответы (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.

person divanov    schedule 17.01.2014
comment
К сожалению, хотя JCE также поддерживает псевдонимы OID (по крайней мере, в 1.8), getAlgorithm() вернет OID :) - person Pawel Veselov; 03.09.2015
comment
Да, провайдер SUN также указал псевдонимы для алгоритмов, но он не разрешает имя алгоритма должным образом. Так что теперь требуется использовать явное имя поставщика безопасности, чтобы получить реализацию BouncyCastle MessageDigest. - person divanov; 19.01.2018
comment
Для BouncyCastle я использовал: BCMessageDigest.getInstance(signer.getDigestAlgOID(), BC).getAlgorithm(); - person user2677034; 21.01.2020

Я нашел ответ. Класс org.bouncycastle.cms.CMSSignedHelper из библиотеки Bouncy Castle имеет сопоставление. Я извлек нужный фрагмент оттуда и скопировал сюда.

...
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);
    }
}
person David Reis    schedule 11.09.2009

Класс org.bouncycastle.cms.CMSSignedGenerator имеет константы для каждого из поддерживаемых алгоритмов. Его константы общедоступны, поэтому их проще использовать, чем CMSSignedHelper, доступный только для пакетов.

person Thiago Chaves    schedule 09.03.2010