2009-09-04 38 views
7

Tôi đang cố gắng tính toán giá trị băm của một mảng byte trong Java. Để có được một cá thể MessageDigest, tôi cần thông báo tên băm, nhưng tôi chỉ có OID băm. Có cách nào khác để làm điều này hoặc một bản đồ hiện có từ hàm băm OID thành tên băm không?Cách lấy tên thuật toán băm bằng cách sử dụng OID trong 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

Loại OID nào? ASN.1? Ai chịu trách nhiệm về các OID này? – Dirk

+0

Đây là OID ASN.1. Các OID này là các OID chuẩn. –

Trả lời

1

Tôi tìm thấy câu trả lời. Lớp org.bouncycastle.cms.CMSSignedHelper từ Bouncy Castle Library có ánh xạ. Tôi trích xuất đoạn trích yêu cầu từ đó và sao chép ở đây.

... 
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

Lớp học org.bouncycastle.cms.CMSSignedGenerator có hằng số cho mỗi thuật toán được hỗ trợ. Các hằng số của nó là công khai, vì vậy chúng dễ sử dụng hơn CMSSignedHelper có thể truy cập vào gói.

3

Hầu hết các nhà cung cấp bảo mật (và BouncyCastle là một trong số họ) xác định không chỉ tên thuật toán đơn lẻ, mà còn cả bí danh, bao gồm OID. Do đó, nó có thể để vượt qua OID trực tiếp đến JCA như thế này:

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

digestAlgorithmName sẽ bằng SHA-1 cuối cùng. Điều này không hoạt động với nhà cung cấp bảo mật SUN.

+1

Thật không may, mặc dù JCE cũng hỗ trợ bí danh OID (ít nhất là 1.8), 'getAlgorithm()' sẽ trả về OID :) –

+0

và điều này không hoạt động trong JDK 1.7 – saurav

+0

Có, nhà cung cấp SUN cũng có bí danh được chỉ định cho các thuật toán, nhưng nó không giải quyết đúng tên thuật toán. Vì vậy, bây giờ nó là cần thiết để sử dụng tên rõ ràng của nhà cung cấp bảo mật để có được thực hiện BouncyCastle của 'MessageDigest'. – divanov

Các vấn đề liên quan