首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用AttributeCertificate从DER文件解析BouncyCastle的未知标记

使用AttributeCertificate从DER文件解析BouncyCastle的未知标记
EN

Stack Overflow用户
提问于 2017-08-28 22:36:30
回答 2查看 6.1K关注 0票数 2

我在使用BouncyCastle Java解析DER属性证书时遇到了问题。

错误

这是我试图使用的代码。我首先以名为InputStream stream的方式读取cert文件,并尝试将其转换为Bouncy城堡AttributeCertificate对象:

代码语言:javascript
复制
ASN1InputStream derIn = new ASN1InputStream(stream);
ASN1Sequence seq = (ASN1Sequence) derIn.readObject();

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

第三行将导致IllegalArgumentException

代码语言:javascript
复制
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)
    ...

Bouncy卡斯尔还抛出一个IOException,表示遇到了一个“未知标记”:

代码语言:javascript
复制
java.io.IOException: unknown tag 28 encountered
    at org.bouncycastle.asn1.ASN1InputStream.buildObject(Unknown Source)
    at org.bouncycastle.asn1.ASN1InputStream.readObject(Unknown Source)
    ...

分析

我已经链接了我要解析的证书文件,这里.本身就是使用OpenSSL生成的。

证书还包括我正在使用的ABAC凭据,它是一个简单的字符串:

代码语言:javascript
复制
[some_uuid].experiment_create <- [some_uuid].partner.experiment_create

我查看了“未知标签28”,看起来ASN.1标记28表示UniversalString。我在网上发现“UniversalString类型将一个Unicode字符串隐式序列化为UTF-32大端字节”。

这在我看来可能是证书中的字符编码问题。但是,当我使用openssl asn1parse查看cert文件时,它似乎很好:

代码语言:javascript
复制
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提供了这样的输出:

代码语言:javascript
复制
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的Bouncy城堡源代码块中,它抛出了我发现的异常:

代码语言:javascript
复制
// 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,还没有被编码,但是我不知道我的证书在哪里被破坏了,或者如何修复这个标记。

有人能指出我的正确方向吗?谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-08-29 02:32:20

您的证书不是有效的属性证书(),它是(几乎有效的)公钥证书,尽管它包含一个扩展OID,用于属性证书(在the 3281/5755中定义),其内容结构不符合标准定义。openssl x509只处理公钥证书;OpenSSL根本不支持属性证书(除非您使用低级别的asn1例程并自己实现一切)。BC支持两者,但实际上几乎没有人使用属性证书。

公钥证书和属性证书的外部包装器都是旧的签名宏,因此该级别成功地进行了解析。第一个字段实际上是错误的-- AttributeCertificateInfo应该以包含1(而不是2)的version INTEGER开头,而实际的TBSCertificate以包含2的version [context0] EXPLICIT INTEGER开始--但是BC没有捕捉到这一点,因为根据v1版本中的源代码,它是可选的和默认的。然后,它尝试解析Holder,它应该是几个带标记的可选项的SEQUENCE,实际上是带标记的整数版本;我不知道它是如何在检测此错误之前设法解析Holder.IssuerSerial的。我不知道它在哪里或者怎么找到标签28。

票数 1
EN

Stack Overflow用户

发布于 2020-11-25 12:29:37

可能不是您的情况,但我在解析OCSP响应时获得了类似的错误:

代码语言:javascript
复制
java.io.IOException: unknown tag 28 encountered
    at org.bouncycastle.asn1.ASN1InputStream.buildObject(Unknown Source)
    at org.bouncycastle.asn1.ASN1InputStream.readObject(Unknown Source)
    at org.bouncycastle.cert.ocsp.OCSPResp.<init>(Unknown Source)
    ...

在我请求获得OCSP响应的请求中缺少了值为application/ocsp-request的头application/ocsp-request,因此我从Bouny城堡的角度获得了无效的数据。

您应该检查正在尝试使用的InputStream/ASN1InputStream/ASN1Sequence

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45928250

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档