我正在 IText 8.0.3 中使用 PdfPadesSigner 的 SignWithBaselineLTAProfile 方法签署 pdf 文档。我在 USB 令牌中使用我的证书作为ExternalSignature (pkcs11library)。一切都很简单。唯一的问题是签名结构中没有 IssuerSerial 匹配。我无法解决这个问题。从现在开始谢谢你。
var padesSigner = new PdfPadesSigner(new PdfReader(content.Document.Stream), signedStream);
IList<IX509Certificate> trusted = new List<IX509Certificate>();
foreach (var crnCert in parameters.TrustedCertificates)
trusted.Add(new X509CertificateBC(crnCert));
padesSigner.SetTrustedCertificates(trusted);
TSAClientBouncyCastle timeStampInfo = null;
if (parameters.TimeStampSettings != null)
timeStampInfo = new TSAClientBouncyCastle(parameters.TimeStampSettings.HostUrl, parameters.TimeStampSettings.LoginId, parameters.TimeStampSettings.Password);
var certificates = new IX509Certificate[]
{
new X509CertificateBC(parameters.SigningCertificate)
};
padesSigner.SignWithBaselineLTAProfile(properties, certificates, this, timeStampInfo);
必须是;
<RelatedCertificate Certificate="CERTIFICATE_FATİH-POLAT_20231017-0920">
<Origin>SIGNED_DATA</Origin>
<Origin>DSS_DICTIONARY</Origin>
<Origin>VRI_DICTIONARY</Origin>
<CertificateRef>
<Origin>SIGNING_CERTIFICATE</Origin>
**<IssuerSerial match="true">MIIBAzCB86SB8DCB7TELMAKGI....</IssuerSerial>**
<DigestAlgoAndValue match="true">
<DigestMethod>SHA256</DigestMethod>
<DigestValue>Fuxst8SamhghugBDp/6FD+kzENHiYzqEyKOXaFZL2jc=</DigestValue>
</DigestAlgoAndValue>
</CertificateRef>
</RelatedCertificate>
我有什么;
<RelatedCertificate Certificate="CERTIFICATE_FATİH-POLAT_20231017-0920">
<Origin>SIGNED_DATA</Origin>
<Origin>DSS_DICTIONARY</Origin>
<Origin>VRI_DICTIONARY</Origin>
<CertificateRef>
<Origin>SIGNING_CERTIFICATE</Origin>
<DigestAlgoAndValue match="true">
<DigestMethod>SHA256</DigestMethod>
<DigestValue>Fuxst8SamhghugBDp/6FD+kzENHiYzqEyKOXaFZL2jc=</DigestValue>
</DigestAlgoAndValue>
</CertificateRef>
</RelatedCertificate>
您显示的 XML 摘录似乎是 eSig DSS 生成的诊断数据。因此,我将在这里解释缺少的条目的含义以及为什么可以缺少它。
此处
CertificateRef
内的 RelatedCertificate
元素表示该证书是从签名的 signingCertificateV2
签名属性引用为签名者证书。
该属性的值在 RFC 5035 中指定为
SigningCertificateV2 ::= SEQUENCE {
certs SEQUENCE OF ESSCertIDv2,
policies SEQUENCE OF PolicyInformation OPTIONAL
}
ESSCertIDv2 ::= SEQUENCE {
hashAlgorithm AlgorithmIdentifier
DEFAULT {algorithm id-sha256},
certHash Hash,
issuerSerial IssuerSerial OPTIONAL
}
Hash ::= OCTET STRING
IssuerSerial ::= SEQUENCE {
issuer GeneralNames,
serialNumber CertificateSerialNumber
}
您在 iText 创建的签名中缺少的
IssuerSerial
元素内的 CertificateRef
元素是指属性值中 issuerSerial
的 ESSCertIDv2
成员。
正如您在定义中已经看到的,这个
issuerSerial
成员被标记为 OPTIONAL
。
因此,观察到
IssuerSerial
元素缺失表明 iText 使用了该 OPTIONAL
ity,并且在 issuerSerial
属性中不包含 signingCertificateV2
成员。
issuerSerial
可以吗?首先,如上所述,根据 RFC 5035,该元素是可选的,因此任何签名处理器(例如验证器)都必须期望签名在其
issuerSerial
属性中不包含 signingCertificateV2
成员。
但是相关规范是否对此进行了更详细的说明?RFC 5035 说
第一个证书在 证书标识符的序列必须是所使用的证书 来验证签名。 ESSCertIDv2 的编码 证书应包含 IssuerSerial 字段。即它
建议包含该字段,乍一看会使 iText 不这样做的决定看起来不合适。
但是此处的 RFC 5035 在 PAdES 签名中的 CAdES 签名容器的上下文中使用,因此 CAdES 和 PAdES 规范可能会修改此建议。CAdES 规范 (ETSI EN 319 122-1) 表示
IssuerSerial元素中的信息只是一个提示,可以帮助识别证书 其摘要与参考中存在的值匹配。但绑定信息是摘要 证书。
(第 5.2.2.3 节“ESS signing-certificate-v2
属性”)此外,在基线配置文件的要求中,该规范甚至说
不应包含
issuerSerial
字段
(第 6.3 节“组件和服务的要求”,“附加要求”,g 项)
PAdES 规范 (ETSI EN 319 142-1) 这里只是说
生成器应使用签名证书或签名证书v2属性,具体取决于哈希值 功能,符合 ETSI EN 319 122-1因此,总的来说
issuerSerial
成员是可选的,不建议使用它。这对您来说意味着什么?
PdfPadesSigner 的 SignWithBaselineLTAProfile 方法创建的签名很好,至少就我们在这里讨论的方面而言,并且您称为“必须是”的摘录实际上只是“可以是”甚至“不应该”。 您的评论“我发现这用于验证签名”表明告诉您这一点的验证者没有正确处理有问题的属性,特别是在 PAdES 签名的上下文中。
旁白:示例中的时间戳有错误
signingCertificateV2
属性编码如下:
SEQUENCE (2 elem)
OBJECT IDENTIFIER 1.2.840.113549.1.9.16.2.47 signingCertificateV2 (S/MIME Authenticated Attributes)
SET (1 elem)
SEQUENCE (1 elem)
SEQUENCE (1 elem)
SEQUENCE (2 elem)
SEQUENCE (2 elem)
OBJECT IDENTIFIER 2.16.840.1.101.3.4.2.1 sha-256 (NIST Algorithm)
NULL
OCTET STRING (32 byte) 2E8EFCDD4C13BCB9F18E2AAD1A5391EEF0415D041171794C51EBD9BB8C5E23EE
签名的属性必须采用 DER 编码。 DER 编码特别意味着“不”包含默认值。
您的时间戳中指示的哈希算法 SHA-256 是默认值(请参阅上面我对 RFC 5035 的引用),因此上面的编码是错误的。
(实际上并没有多少验证器在这个深度上检查签名属性的 DER 编码,但有些验证器这样做了。在最近的 ETSI 插件测试中,至少有一个参与者的软件确实检查了这一点。因此,使用这些时间戳,您的签名可能会经常被接受,但有时突然不被接受。)
顺便说一句,时间戳中的这些 signingCertificateV2
属性也不包括可选的
issuerSerial
成员...;)
我也遇到了你在消息中提到的同样情况。对于上述情况,你能制定出解决方案吗?