2017-08-28 312 views
0

我遇到了使用BouncyCastle Java API解析DER屬性證書的問題。未知標記遇到從BouncyCastle DER文件解析AttributeCertificate

錯誤

這是我試圖使用的代碼。我第一次看的證書文件命名爲stream一個InputStream,並嘗試將其轉換爲BouncyCastle的AttributeCertificate對象:

ASN1InputStream derIn = new ASN1InputStream(stream); 
ASN1Sequence seq = (ASN1Sequence) derIn.readObject(); 

AttributeCertificate cert = AttributeCertificate.getInstance(seq); <-- exception here 
ac = new X509AttributeCertificateHolder(cert); 

第三行導致IllegalArgumentException

IllegalArgumentException: unknown object in getInstance: org.bouncycastle.asn1.ASN1Integer 
    at org.bouncycastle.asn1.ASN1Sequence.getInstance(Unknown Source) 
    at org.bouncycastle.asn1.x509.IssuerSerial.getInstance(Unknown Source) 
    at org.bouncycastle.asn1.x509.Holder.getInstance(Unknown Source) 
    at org.bouncycastle.asn1.x509.AttributeCertificateInfo.getInstance(Unknown Source) 
    ... 

BouncyCastle的也會引發IOException說遇到「未知標籤」:

java.io.IOException: unknown tag 28 encountered 
    at org.bouncycastle.asn1.ASN1InputStream.buildObject(Unknown Source) 
    at org.bouncycastle.asn1.ASN1InputStream.readObject(Unknown Source) 
    ... 

分析

我已經鏈接了我試圖解析的證書文件here證書本身是使用OpenSSL生成的。

該證書也包括我使用的ABAC證書,這是一個簡單的字符串:

[some_uuid].experiment_create <- [some_uuid].partner.experiment_create 

我看着「未知標籤28」,似乎ASN.1標記28表示UniversalString。我在網上發現:「UniversalString類型將隱式序列化爲UTF-32 big endian的Unicode字符串建模。」

這對我來說在cert中提出了一個可能的字符編碼問題。但是,當我看着使用openssl asn1parse的證書文件,它似乎罰款:

0:d=0 hl=4 l= 660 cons: SEQUENCE   
4:d=1 hl=4 l= 509 cons: SEQUENCE   
8:d=2 hl=2 l= 3 cons: cont [ 0 ]   
10:d=3 hl=2 l= 1 prim: INTEGER   :02 
13:d=2 hl=2 l= 1 prim: INTEGER   :00 
16:d=2 hl=2 l= 13 cons: SEQUENCE   
18:d=3 hl=2 l= 9 prim: OBJECT   :sha256WithRSAEncryption 
29:d=3 hl=2 l= 0 prim: NULL    
31:d=2 hl=2 l= 51 cons: SEQUENCE   
33:d=3 hl=2 l= 49 cons: SET    
35:d=4 hl=2 l= 47 cons: SEQUENCE   
37:d=5 hl=2 l= 3 prim: OBJECT   :commonName 
42:d=5 hl=2 l= 40 prim: UTF8STRING  :bf3a72c271f661dae81647a16c1babf3a52da28e 
84:d=2 hl=2 l= 30 cons: SEQUENCE   
86:d=3 hl=2 l= 13 prim: UTCTIME   :170828213103Z 
101:d=3 hl=2 l= 13 prim: UTCTIME   :270826213103Z 
116:d=2 hl=2 l= 51 cons: SEQUENCE   
118:d=3 hl=2 l= 49 cons: SET    
120:d=4 hl=2 l= 47 cons: SEQUENCE   
122:d=5 hl=2 l= 3 prim: OBJECT   :commonName 
127:d=5 hl=2 l= 40 prim: UTF8STRING  :bf3a72c271f661dae81647a16c1babf3a52da28e 
169:d=2 hl=3 l= 159 cons: SEQUENCE   
172:d=3 hl=2 l= 13 cons: SEQUENCE   
174:d=4 hl=2 l= 9 prim: OBJECT   :rsaEncryption 
185:d=4 hl=2 l= 0 prim: NULL    
187:d=3 hl=3 l= 141 prim: BIT STRING   
331:d=2 hl=3 l= 183 cons: cont [ 3 ]   
334:d=3 hl=3 l= 180 cons: SEQUENCE   
337:d=4 hl=3 l= 144 cons: SEQUENCE   
340:d=5 hl=2 l= 8 prim: OBJECT   :id-aca-group 
350:d=5 hl=3 l= 131 prim: OCTET STRING  [HEX DUMP]:0C8180626633613732633237316636363164616538313634376131366331626162663361353264613238652E6578706572696D656E745F637265617465203C2D20626633613732633237316636363164616538313634376131366331626162663361353264613238652E706172746E65722E6578706572696D656E745F637265617465 
484:d=4 hl=2 l= 31 cons: SEQUENCE   
486:d=5 hl=2 l= 3 prim: OBJECT   :X509v3 Authority Key Identifier 
491:d=5 hl=2 l= 24 prim: OCTET STRING  [HEX DUMP]:30168014162E4EF6CD52F37CD2EDDFBEA484E70D6CDE9048 
517:d=1 hl=2 l= 13 cons: SEQUENCE   
519:d=2 hl=2 l= 9 prim: OBJECT   :sha256WithRSAEncryption 
530:d=2 hl=2 l= 0 prim: NULL    
532:d=1 hl=3 l= 129 prim: BIT STRING   

其他程序也似乎做工精細; openssl x509提供了這個輸出:

Certificate: 
    Data: 
     Version: 3 (0x2) 
     Serial Number: 0 (0x0) 
    Signature Algorithm: sha256WithRSAEncryption 
     Issuer: CN=bf3a72c271f661dae81647a16c1babf3a52da28e 
     Validity 
      Not Before: Aug 28 21:31:03 2017 GMT 
      Not After : Aug 26 21:31:03 2027 GMT 
     Subject: CN=bf3a72c271f661dae81647a16c1babf3a52da28e 
     Subject Public Key Info: 
      Public Key Algorithm: rsaEncryption 
       Public-Key: (1024 bit) 
       Modulus: 
        00:c5:d4:35:49:4d:bd:ee:9a:93:51:a4:e1:46:df: 
        46:c0:1e:f6:b1:85:70:4d:31:2b:20:6f:ab:82:16: 
        b4:9d:3e:ea:f3:38:53:e2:7b:be:36:37:f3:11:7f: 
        90:5d:aa:ad:e7:e8:61:3c:46:8d:7a:69:4d:c6:89: 
        e2:f7:07:d9:3f:b0:5d:f7:ee:40:e5:86:48:7b:4c: 
        0e:0f:11:0c:96:41:e6:99:02:17:df:4e:60:3d:d0: 
        42:b5:dc:22:e0:64:6d:ad:17:22:b7:a2:15:ec:dd: 
        89:c2:b4:58:01:64:d7:db:fe:62:1e:c5:40:0c:e0: 
        b9:12:7e:fe:4c:31:65:e6:51 
       Exponent: 65537 (0x10001) 
     X509v3 extensions: 
      id-aca-group: 
       ...bf3a72c271f661dae81647a16c1babf3a52da28e.experiment_create <- bf3a72c271f661dae81647a16c1babf3a52da28e.partner.experiment_create 
      X509v3 Authority Key Identifier: 
       keyid:16:2E:4E:F6:CD:52:F3:7C:D2:ED:DF:BE:A4:84:E7:0D:6C:DE:90:48 

    Signature Algorithm: sha256WithRSAEncryption 
     1e:0f:2a:7a:cf:95:77:0f:5c:48:f3:12:c4:b9:8a:5a:d9:b9: 
     62:1c:60:0c:a0:13:70:f3:c5:aa:de:6d:6f:92:7f:0d:a2:3b: 
     c9:bd:cc:45:6c:4b:21:8d:32:81:8b:af:13:6e:a3:96:18:05: 
     3b:83:fb:8c:3b:2a:d8:87:22:56:9e:4b:1d:06:e6:7f:ba:36: 
     89:e8:c6:8a:5a:9e:2c:9b:44:5e:19:fe:68:13:12:93:48:df: 
     f9:34:42:01:d5:62:c1:ca:e4:e2:3b:86:b7:4c:75:ba:60:5b: 
     c9:f7:68:9a:b0:b5:1c:33:01:5e:77:c0:7c:13:11:e1:09:67: 
     42:dd 

基於這些,我找不到證書的任何明顯錯誤。我能找到的唯一的線索是在ASN1InputStream.java的BouncyCastle的源代碼塊,其拋出,我發現了異常:

// Build an object given its tag and the number of bytes to construct it from. 
    protected ASN1Primitive buildObject(
     int  tag, 
     int  tagNo, 
     int  length) 
     throws IOException 
    { 
     ... 
     if (isConstructed) 
     { 
      // TODO There are other tags that may be constructed (e.g. BIT_STRING) 
      switch (tagNo) 
      { 
       case OCTET_STRING: 
        // 
        // yes, people actually do this... 
        // 
        ASN1EncodableVector v = buildDEREncodableVector(defIn); 
        ASN1OctetString[] strings = new ASN1OctetString[v.size()]; 

        for (int i = 0; i != strings.length; i++) 
        { 
         strings[i] = (ASN1OctetString)v.get(i); 
        } 

        return new BEROctetString(strings); 
       case SEQUENCE: 
        if (lazyEvaluate) 
        { 
         return new LazyEncodedSequence(defIn.toByteArray()); 
        } 
        else 
        { 
         return DERFactory.createSequence(buildDEREncodableVector(defIn)); 
        } 
       case SET: 
        return DERFactory.createSet(buildDEREncodableVector(defIn)); 
       case EXTERNAL: 
        return new DERExternal(buildDEREncodableVector(defIn));     
       default: 
        throw new IOException("unknown tag " + tagNo + " encountered"); 
      } 
     } 

     return createPrimitiveDERObject(tagNo, defIn, tmpBuffers); 
    } 

看來這些支持「可能構成的其它標籤」,包括標籤28,不是招」目前還沒有編碼,但我不確定我的證書破損或如何修復標籤。

任何人都可以指向正確的方向嗎?謝謝。

回答

1

您的證書是不是有效的屬性證書,它是(近有效)的公鑰證書,儘管它包含內容旨在與屬性證書使用(在rfc3281定義/ 5755)的擴展OID不符合標準定義的結構。 openssl x509句柄只有公鑰證書; OpenSSL根本不支持屬性證書(除非您使用低級別的asn1例程並自行實現所有內容)。 BC支持兩者,但實際上幾乎沒有人使用屬性證書。

public-key和attribute certs的外部包裝是舊的SIGNED宏,因此該級別解析成功。第一個字段實際上是錯誤的 - AttributeCertificateInfo應該以包含1(不是2)的version INTEGER開始,並且您的實際TBSCertificate開始於包含2的有效version [context0] EXPLICIT INTEGER - 但是BC不會理解這一點,因爲根據v1版本中的來源是可選的和默認的。然後它嘗試解析Holder,它應該是幾個標記的可選項目的SEQUENCE,它們實際上是tagged-INTEGER版本;我不確定它如何設法在檢測到此錯誤之前嘗試解析Holder.IssuerSerial。我不知道它在哪裏或如何找到一個標籤28.