繁体   English   中英

如何在没有完整 X509 证书的情况下使用 PdfPkcs7?

[英]How to use PdfPkcs7 without a full X509 certificate?

我们正在尝试通过移动签名服务在外部对 PDF 进行签名。 Stackoverflow 中有很多关于这个主题的问题,尤其是来自土耳其的问题。 请参阅: 使用 ITextSharp 和 XML 签名签署 Pdf 这里也一样。

我们要求 MSSP 提供个人资料信息。 由于个人数据保护的法律,我们无法检索签名者的完整公共证书或链。

档案查询服务响应:

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
    <soap:Body>
        <ns1:MSS_ProfileQueryResponse xmlns:ns1="http://turkcelltech.com/mobilesignature/validation/soap">
            <MSS_ProfileResp xmlns:ns2="http://www.w3.org/2000/09/xmldsig#" xmlns:ns3="http://www.w3.org/2001/04/xmlenc#" xmlns:ns4="http://www.w3.org/2003/05/soap-envelope" xmlns:ns5="http://uri.etsi.org/TS102204/v1.1.2#" MajorVersion="1" MinorVersion="1">
                <ns5:AP_Info AP_ID="http://localhost" AP_TransID="_1264751036088" AP_PWD="secret" Instant="2013-06-12T04:54:43.260Z"/>
                <ns5:MSSP_Info Instant="2020-07-22T18:43:33.723+03:00">
                    <ns5:MSSP_ID/>
                </ns5:MSSP_Info>
                <ns5:SignatureProfile>
                    <ns5:mssURI>http://uri.turkcellteknoloji.com.tr/MobileSignature/profile2</ns5:mssURI>
                    <ns5:CertIssuerDN>C=TR,O=Elektronik Bilgi Guvenligi A.S.,CN=Turkcell Mobil NES Hizmet Saglayicisi S2</ns5:CertIssuerDN>
                    <ns5:CertSerialNumber>313460597714010174158784514408553193353</ns5:CertSerialNumber>
                    <ns5:CertHash>
                        <ns5:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
                        <ns5:DigestValue>MVI4FeeToX6TDPLh3h9zEw19ulzTomxPB/zDvnyWzKA=</ns5:DigestValue>
                    </ns5:CertHash>
                    <ns5:msspUrl>http://localhost</ns5:msspUrl>
                    <ns5:certIssuerDN-DER>MGoxCzAJBgNVBAYTAlRSMSgwJgYDVQQKDB9FbGVrdHJvbmlrIEJpbGdpIEd1dmVubGlnaSBBLlMuMTEwLwYDVQQDDChUdXJrY2VsbCBNb2JpbCBORVMgSGl6bWV0IFNhZ2xheWljaXNpIFMy</ns5:certIssuerDN-DER>
                </ns5:SignatureProfile>
                <ns5:Status>
                    <ns5:StatusCode Value="100"/>
                    <ns5:StatusMessage>REQUEST_OK</ns5:StatusMessage>
                </ns5:Status>
            </MSS_ProfileResp>
        </ns1:MSS_ProfileQueryResponse>
    </soap:Body>
</soap:Envelope>

我们仍然可以使用此信息创建一个 SigningCertificateV2 实例。

var certAlgorithmIdentifier = new AlgorithmIdentifier(certHashDigestAlgorithm);
var certHash = Convert.FromBase64String(certHashDigestValue);

var issuer = new GeneralNames(new GeneralName(new X509Name(certIssuerDN)));
var serial = new DerInteger(new BigInteger(certSerialNumber));
var issuerSerial = new IssuerSerial(issuer, serial);

var certIDv2 = new EssCertIDv2(certAlgorithmIdentifier, certHash, issuerSerial);

return new SigningCertificateV2(certIDv2);

ASN.1 结果是:

SEQUENCE (1 elem)
  SEQUENCE (1 elem)
    SEQUENCE (3 elem)
      SEQUENCE (1 elem)
        OBJECT IDENTIFIER 1.2.840.113549.1.1.11 sha256WithRSAEncryption (PKCS #1)
      OCTET STRING (32 byte) 31523815E793A17E930CF2E1DE1F73130D7DBA5CD3A26C4F07FCC3BE7C96CCA0
      SEQUENCE (2 elem)
        SEQUENCE (1 elem)
          [4] (1 elem)
            SEQUENCE (3 elem)
              SET (1 elem)
                SEQUENCE (2 elem)
                  OBJECT IDENTIFIER 2.5.4.6 countryName (X.520 DN component)
                  PrintableString TR
              SET (1 elem)
                SEQUENCE (2 elem)
                  OBJECT IDENTIFIER 2.5.4.10 organizationName (X.520 DN component)
                  UTF8String Elektronik Bilgi Guvenligi A.S.
              SET (1 elem)
                SEQUENCE (2 elem)
                  OBJECT IDENTIFIER 2.5.4.3 commonName (X.520 DN component)
                  UTF8String Turkcell Mobil NES Hizmet Saglayicisi S2
        INTEGER (128 bit) 313460597714010174158784514408553193353

我们还可以从 CA 的钥匙串中检索、根证书和中间证书。

那么,我们如何将它们与 PdfSigner 和 PdfPKCS7 结合使用来签署 PDF? 我们应该在外部创建 CMSSignedData 吗?如何创建? 这个路线图正确吗?

  1. 根据 ByteRange 的 PDF 内容计算摘要。
  2. 在外部创建一个 Cms 容器。 (不知何故)
  3. 添加签名者信息,并将内容摘要放入容器中。
  4. 根据 CMS 认证的属性计算摘要。
  5. 通过 MSSP 签署最终摘要,并检索 XMLDSig。
  6. 将签名字段添加到现有 Cms 容器。
  7. 在 PDF 签名字典中填写 /Contents,使用 DER 编码的 CmsSignedData。

我知道有很多关于同一主题的问题。 但它们都不够清楚,无法解释处理签名证书的过程。

编辑:

澄清一下,当我们发送 SHA-256 摘要(base64 编码)时,我们将在签名请求后检索 X509 证书。

XML 签名,从签名服务返回:

<?xml version="1.0" encoding="UTF-8" ?>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
    <SignedInfo>
        <CanonicalizationMethod Algorithm=""/>
        <SignatureMethod Algorithm=""/>
        <Reference>
            <DigestMethod Algorithm=""/>
            <DigestValue/>
        </Reference>
    </SignedInfo>
    <SignatureValue>
        ...
    </SignatureValue>
    <KeyInfo>
        <KeyValue>
            <RSAKeyValue>
                <Modulus>
                    ...
                </Modulus>
                <Exponent>
                    ...
                </Exponent>
            </RSAKeyValue>
        </KeyValue>
        <X509Data>
            <X509Certificate>
                ...
            </X509Certificate>
        </X509Data>
    </KeyInfo>
</Signature>

但正如我之前提到的,我们无法在签名请求之前检索签名者的完整公共证书。 仅证书 hash、序列号和颁发者 DN。 此信息足以在签名请求之前设置ESS signing-certificate-v2属性。

https://tools.ietf.org/html/rfc5126#section-5.7.3

这就是为什么我们应该能够在本地创建 CmsSignedData,并添加 pdf 内容摘要、签名者信息(从配置文件查询中检索到的签名证书 v2)并从该 CmsSignedData 实例中获取最终摘要,以使用 MSSP 签名服务进行签名。 之后,当我们从服务中检索 XML 签名时,我们可以在此 CmsSignedData 实例中填充其他未签名属性、证书。

在回答问题的第一个版本时,给人的印象是完整的签名者证书根本不可用,甚至在签名服务答案中也不可用:

如果不嵌入签名者的 X509 证书,则无法创建 pdf 签名。

至少不是以可互操作的方式。

根据 pdf 规范:

12.8.3.2 PKCS #1 签名

[...] 对于使用 PKCS #1 签署 PDF 文件,应使用的 SubFilter 的唯一值是adbe.x509.rsa_sha1 [...] 签名者的证书链应存储在 Cert 条目中。

12.8.3.3 CMS (PKCS #7) 签名

[...] SubFilter 应采用以下值之一:

  • adbe.pkcs7.detached [...]
  • adbe.pkcs7.sha1 [...]

CMS object 至少应包含签名者的 X.509 签名证书。 该证书用于验证 Contents 中的签名值。

(ISO 32000-2,第 12.8.3 节签名互操作性)

如果您正在查看 PAdES 签名,请根据 PAdES 规范:

6.3 PAdES 基线签名

[...]

其他要求:

a) 生成器应在 SignedData.certificates 字段中包含签名证书。

(ETSI EN 319 142-1 V1.1.1)

因此,如果没有签名者的 X509 证书,您将无法创建可互操作的 pdf 签名。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM