2010-03-09 401 views
14

我正在嘗試從數字證書中讀取自定義擴展名。我知道該值是在DER中編碼的GeneralString。有沒有簡單的方法來正確解碼並獲得Java字符串?我嘗試了以下內容,但's'在字符串的開始處包含一些編碼元數據作爲垃圾字符。如何在Java中解碼DER編碼的字符串?

byte[] ext = cert.getExtensionValue("1.2.3.4"); 
String s= new String(ext); 
System.out.println(s); 

是否有一個快速簡便的方法來做到這一點?或者我真的需要使用一些完整的ASN.1庫嗎?

謝謝!

回答

6

BouncyCastle是(一切中):

庫用於讀取和寫入ASN.1編碼的對象。

9

這原來是非常簡單與BouncyCastle的:

private String getExtensionValue(X509Certificate X509Certificate, String oid) throws IOException 
{ 
    String decoded = null; 
    byte[] extensionValue = X509Certificate.getExtensionValue(oid); 

    if (extensionValue != null) 
    { 
     DERObject derObject = toDERObject(extensionValue); 
     if (derObject instanceof DEROctetString) 
     { 
      DEROctetString derOctetString = (DEROctetString) derObject; 

      derObject = toDERObject(derOctetString.getOctets()); 
      if (derObject instanceof DERUTF8String) 
      { 
       DERUTF8String s = DERUTF8String.getInstance(derObject); 
       decoded = s.getString(); 
      } 

     } 
    } 
    return decoded; 
} 

private DERObject toDERObject(byte[] data) throws IOException 
{ 
    ByteArrayInputStream inStream = new ByteArrayInputStream(data); 
    ASN1InputStream asnInputStream = new ASN1InputStream(inStream); 

    return asnInputStream.readObject(); 
} 
+1

喜看起來像DERObject已被棄用。任何機會,你可以更新你的代碼示例。想想你現在必須使用org.bouncycastle.sasn1.Asn1Object,但我還沒有能夠使它工作。 – user1513388 2012-11-04 22:26:15

+0

@ user1513388對不起,這是2年多前。我現在甚至沒有在任何東西中使用Java,所以我不確定是否/當我可能會嘗試再次嘗試。 – Ragesh 2012-11-05 07:26:46

+0

正確的感謝您的回覆! – user1513388 2012-11-05 10:31:02

10

包含在下頁上的使用說明我已經做了一些修改和代碼工作的罰款和我在一起。

從早期版本的BC移植到1.47以後 - 的充氣城堡 http://www.bouncycastle.org/wiki/display/JA1/Porting+from+earlier+BC+releases+to+1.47+and+later

private String getExtensionValue(X509Certificate X509Certificate, String oid) throws IOException 
{ 
    String decoded = null; 
    byte[] extensionValue = X509Certificate.getExtensionValue(oid); 

    if (extensionValue != null) 
    { 
     ASN1Primitive derObject = toDERObject(extensionValue); 
     if (derObject instanceof DEROctetString) 
     { 
      DEROctetString derOctetString = (DEROctetString) derObject; 

      derObject = toDERObject(derOctetString.getOctets()); 
      if (derObject instanceof ASN1String) 
      { 
       ASN1String s = (ASN1String)derObject; 
       decoded = s.getString(); 
      } 

     } 
    } 
    return decoded; 
} 

/** 
* From http://stackoverflow.com/questions/2409618/how-do-i-decode-a-der-encoded-string-in-java 
*/ 
private ASN1Primitive toDERObject(byte[] data) throws IOException 
{ 
    ByteArrayInputStream inStream = new ByteArrayInputStream(data); 
    ASN1InputStream asnInputStream = new ASN1InputStream(inStream); 

    return asnInputStream.readObject(); 
} 
1

JcaX509ExtensionUtils軍團做什麼的答案在一個更簡單的方式做以上。

X509Certificate certificate; 
byte[] encodedExtensionValue = certificate.getExtensionValue(oid); 
if (encodedExtensionValue != null) { 
    ASN1Primitive extensionValue = JcaX509ExtensionUtils 
      .parseExtensionValue(encodedExtensionValue); 
    String values = extensionValue.toString();   
}