从BC源码看PKCS10 CSR(Certificate Signing Request)的结构和构造过程

BC库使用PKCS10CertificationRequestBuilder来构造CSR,该类的注释里其实很清楚的描述了CSR的结构,如下所示:

   CertificationRequest ::= SEQUENCE {
     certificationRequestInfo  CertificationRequestInfo,
     signatureAlgorithm        AlgorithmIdentifier{{ SignatureAlgorithms }},
     signature                 BIT STRING
   }
  
   CertificationRequestInfo ::= SEQUENCE {
     version             INTEGER { v1(0) } (v1,...),
     subject             Name,
     subjectPKInfo   SubjectPublicKeyInfo{{ PKInfoAlgorithms }},
     attributes          [0] Attributes{{ CRIAttributes }}
    }
  
    Attributes { ATTRIBUTE:IOSet } ::= SET OF Attribute{{ IOSet }}
  
    Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE {
      type    ATTRIBUTE.&id({IOSet}),
      values  SET SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{\@type})
    }

下面稍加注释:

CertificationRequest即为CSR结构,可以看到,它包含了三部分:

  1. certificationRequestInfo:CSR基本信息。
  2. signatureAlgorithm:对CSR基本信息签名时使用的签名算法。
  3. signature:对CSR基本信息的签名,当然一般是使用私钥来进行签名,CA在签发证书时是会使用certificationRequestInfo里的公钥来验签。

CertificationRequestInfo,CSR基本信息,其结构包含了以下四部分:

  1. version:版本号。
  2. subject:使用者信息。
  3. subjectPKInfo:公钥信息,里面又包含了非对称算法标识和公钥数据两部分。
  4. attributes:其他属性集合。

CSR的构建过程主要体现在PKCS10CertificationRequestBuilder的build方法中,理解了CSR的结构,其实其构造过程也就很好理解了,主要就是DER编码和签名:

public PKCS10CertificationRequest build(
        ContentSigner signer)
    {
        CertificationRequestInfo info;

        if (attributes.isEmpty())
        {
            //如果其他属性集合是空的,通过leaveOffEmpty来判断是否要编码一个空的集合到CSR中
            if (leaveOffEmpty)
            {
                info = new CertificationRequestInfo(subject, publicKeyInfo, null);
            }
            else
            {
                info = new CertificationRequestInfo(subject, publicKeyInfo, new DERSet());
            }
        }
        else
        {
            ASN1EncodableVector v = new ASN1EncodableVector();

            for (Iterator it = attributes.iterator(); it.hasNext(); )
            {
                v.add(Attribute.getInstance(it.next()));
            }

            //将使用者信息、公钥信息、其他属性集合填充到CSR基本信息中
            info = new CertificationRequestInfo(subject, publicKeyInfo, new DERSet(v));
        }

        try
        {
            OutputStream sOut = signer.getOutputStream();

            //把CSR基本信息经过DER编码后塞到签名对象中,准备对CSR基本信息进行签名。signer中持有对应的私钥以及签名算法标识。
            sOut.write(info.getEncoded(ASN1Encoding.DER));

            sOut.close();

            //CSR基本信息、签名算法、对CSR基本信息的签名值,就构成了一个符合PKCS10标准的CSR
            return new PKCS10CertificationRequest(new CertificationRequest(info, signer.getAlgorithmIdentifier(), new DERBitString(signer.getSignature())));
        }
        catch (IOException e)
        {
            throw new IllegalStateException("cannot produce certification request signature");
        }
    }

猜你喜欢

转载自blog.csdn.net/K0000000r/article/details/82455389
今日推荐