2009-09-04 4 views
7

Estoy tratando de calcular el hash de una matriz de bytes en Java. Para obtener una instancia de MessageDigest, necesito informar el nombre de hash, pero solo tengo el OID de hash. ¿Hay alguna otra manera de hacer esto o un mapa existente desde hash OID a nombres hash?¿Cómo obtener el nombre del algoritmo hash usando el OID en Java?

String oid = "1.2.3.4.5"; 
String digestAlgorithmName = getDigestAlgorithmName(oid); 

MessageDigest messageDigest = MessageDigest.getInstance(digestAlgorithmName); 
byte[] actualHash = messageDigest.digest(new byte[] { 0x00 }); 
+0

¿Qué tipo de OID es ese? ASN.1? ¿Quién está a cargo de estos OID? – Dirk

+0

Es un OID ASN.1. Estos OID son los estandarizados. –

Respuesta

1

Encontré una respuesta. La clase org.bouncycastle.cms.CMSSignedHelper desde Bouncy Castle Library tiene la asignación. Extraje el fragmento requerido de allí y copié aquí.

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

La clase org.bouncycastle.cms.CMSSignedGenerator tiene constantes para cada uno de sus algoritmos soportados. Sus constantes son públicas, por lo que son más fáciles de usar que CMSSignedHelper accesible solo para paquetes.

3

La mayoría de los proveedores de seguridad (y BouncyCastle es uno de ellos) define no solo un nombre de algoritmo, sino también alias, que incluyen OID. Por lo tanto, es posible pasar directamente a OID JCA como esto:

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

digestAlgorithmName será igual a SHA-1 en el final. Esto no funciona con el proveedor de seguridad de SUN.

+1

Desafortunadamente, aunque JCE también admite alias de OID (al menos en 1.8), 'getAlgorithm()' devolvería el OID :) –

+0

y esto no funciona en JDK 1.7 – saurav

+0

Sí, el proveedor de SUN también tiene alias especificados para los algoritmos, pero no resuelve el nombre del algoritmo correctamente. Por lo tanto, ahora es necesario utilizar el nombre explícito del proveedor de seguridad para obtener la implementación de BouncyCastle del 'MessageDigest'. – divanov

Cuestiones relacionadas