【发布时间】: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 的钥匙串中检索根证书和中间证书。
- https://www.e-guven.com/media/2582/eguvenkoks2.crt
- https://www.e-guven.com/media/2584/turkcellmobilimzaaltkoks2.crt
那么,我们如何将它们与 PdfSigner 和 PdfPKCS7 结合使用来签署 PDF?我们应该在外部创建 CMSSignedData 吗?如何创建?这个路线图正确吗?
- 根据 ByteRange 的 PDF 内容计算摘要。
- 在外部创建一个 Cms 容器。 (不知何故)
- 添加签名者信息,并将内容摘要放入容器中。
- 根据 CMS 验证的属性计算摘要。
- 通过 MSSP 签署最终摘要,并检索 XMLDSig。
- 将签名字段添加到现有 Cms 容器。
- 使用 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 属性的签名容器,因此它只需要证书在签名之后。这足以用于 Adobe Reader 验证,但不适用于 PAdES...不过,调整示例以使用签名属性并包含您计算的
SigningCertificateV2实例应该很容易...
标签: c# .net-core itext7 pkcs#7