【问题标题】:How to use PdfPkcs7 without a full X509 certificate?如何在没有完整 X509 证书的情况下使用 PdfPkcs7?
【发布时间】:2020-08-09 06:34:15
【问题描述】:

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

我们要求 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. 使用 DER 编码的 CmsSignedData 填充 PDF 签名字典中的 /Contents。

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

编辑:

澄清一下,当我们发送 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>

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

https://www.rfc-editor.org/rfc/rfc5126#section-5.7.3

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

【问题讨论】:

  • 编辑后:你看过代码here了吗?它创建一个没有 ESS SigningCertificateV2 属性的签名容器,因此它只需要证书签名之后。这足以用于 Adob​​e Reader 验证,但不适用于 PAdES...不过,调整示例以使用签名属性并包含您计算的 SigningCertificateV2 实例应该很容易...

标签: c# .net-core itext7 pkcs#7


【解决方案1】:

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

如果不嵌入签名者的 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 对象至少应包含签名者的 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 签名。

【讨论】:

  • 那么,ETSI.CAdES.detached 作为子过滤器怎么样。据我所知,在这种情况下禁止输入证书。
  • “那么,作为子过滤器的 ETSI.CAdES.detached 怎么样。” - 这些是 PAdES 签名。因此,请参阅最后的报价。 “据我所知,在这种情况下禁止输入证书。” - 是的。明显地。 “顺便说一句,我已经编辑了这个问题” - 这个编辑确实完全改变了这个问题。
  • 该编辑确实完全改变了问题 - 我的错误,抱歉。好吧,我可以考虑你的答案,因为它不再是不可能的了吗?
  • 一般来说也不是不可能的。 (至少我是这么认为的,我还没有详细检查你的xmls。)但是你不能使用PdfPKCS7来创建签名容器。您可以尝试从中派生自己的类,而不是证书只需要准备SigningCertificateV2,然后才需要完整的证书。
猜你喜欢
  • 2010-12-09
  • 2023-03-23
  • 2021-02-10
  • 1970-01-01
  • 2020-05-23
  • 1970-01-01
  • 2015-08-22
  • 1970-01-01
相关资源
最近更新 更多