- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我已经使用 iText 7 创建了代码,该代码能够使用使用 ECDSA key 对的 X509 证书对给定的 PDF 进行数字签名。当我在 Acrobat Reader DC 中打开这个签名的 PDF 时,它会正确读取它,并验证它是否有效(意思是文档自签名后未被修改,等等)。
但是,当我尝试使用 iText 7 验证同一文档时,完整性和真实性检查返回 false。
这是一个示例代码:
// ...
PdfDocument pdfDoc = new(new PdfReader(stream));
SignatureUtil signUtil = new(pdfDoc);
IList<string> names = signUtil.GetSignatureNames();
foreach (string name in names) {
PdfPKCS7 pkcs7 = signUtil.ReadSignatureData(name);
bool wholeDocument = signUtil.SignatureCoversWholeDocument(name);
bool signatureIntegrityAndAuthenticity = pkcs7.VerifySignatureIntegrityAndAuthenticity(); // this returns false, even though Adobe has no problem verifying the signature.
// more code to read values and put them in a json
}
// ...
以及我从签名中提取的示例输出:
{
"$id": "1",
"signatures": [
{
"$id": "2",
"integrityAndAuthenticity": false, // <---- should be true in my opinion.
"revisionNumber": 1,
"coversWholeDocument": true,
"invisibleSignature": true,
"filterSubType": "ETSI.CAdES.detached",
"encryptionAlgorithm": "ECDSA",
"hashAlgorithm": "SHA512",
"nameOfSigner": "C=HU, CN=Teszt Elek, GIVENNAME=Elek, L=Budapest, O=Teszt ECC Szervezet, SN=202010260807, SURNAME=Teszt",
"alternateNameOfSigner": null,
"signDate": "2021-04-22T12:50:33Z",
"timestamp": {
"$id": "3",
"signDate": "2021-04-22T12:50:33Z",
"service": "C=HU,L=Budapest,O=Microsec Ltd.,2.5.4.97=VATHU-23584497,CN=Test e-Szigno TSA 2017 01",
"verified": true,
"hashAlgorithmOid": "2.16.840.1.101.3.4.2.3"
},
"location": " Hungary",
"reason": "Approval",
"contactInfo": "",
"name": "GUID_97e1669d-0fbe-409a-a8fc-8518a1bae460",
"signatureType": "approval",
"fillInAllowed": true,
"annotationsAllowed": true,
"fieldLocks": []
}
],
"revisions": 1,
"valid": false // is an aggregate of all the signatures integrity in the array above
}
发布时我使用的是最新的 iText 7 版本,我的平台是 ASP.NET 5 (.Net 5)。示例代码对应于 iText 自己的示例代码,它们为他们的学习书籍提供(但更新为 7,因为书籍是为 iText 5 编写的)。
我在 this google drive 中添加了一个样本 pdf 和一些签名版本的组合.它包含一个示例 pdf,它是未签名的和纯的。然后使用 ECDSA 和 RSA key 分别对该 pdf 进行签名。然后用相反类型的 key 对它们进行签名。以及他们所有的验证结果。注意:在 json 文件中 integrityAndAuthenticity
只是命名为 valid
为了简洁,但它持有的值是 pkcs7.VerifySignatureIntegrityAndAuthenticity()
的结果.所有签名均由我的应用程序完成(使用 iText 7)。
编辑 #1:我正在提供执行签名的代码:
using System;
using System.Security.Cryptography;
using iText.Signatures;
public class EcdsaSignature : IExternalSignature
{
private readonly string _encryptionAlgorithm;
private readonly string _hashAlgorithm;
private readonly ECDsa _pk;
public EcdsaSignature(ECDsa pk, string hashAlgorithm)
{
_pk = pk;
_hashAlgorithm = DigestAlgorithms.GetDigest(DigestAlgorithms.GetAllowedDigest(hashAlgorithm));
_encryptionAlgorithm = "ECDSA";
}
public virtual string GetEncryptionAlgorithm()
{
return _encryptionAlgorithm;
}
public virtual string GetHashAlgorithm()
{
return _hashAlgorithm;
}
public virtual byte[] Sign(byte[] message)
{
return _pk.SignData(message, new HashAlgorithmName(_hashAlgorithm), DSASignatureFormat.Rfc3279DerSequence); // <---- I have solved the iText 7 issue by providing this enum to the SignData() method.
}
}
然后:
using (var key = myCertificate.GetECDsaPrivateKey()) {
/*PdfSigner*/ signer.SignDetached(new EcdsaSignature(key, DigestAlgorithms.SHA512), chainArray, crlList, ocspClient, tsaClient, 0, subfilter);
}
感谢@mkl 的回复,它消除了一些关于签名格式的困惑,幸好 Microsoft 在 SignData()
方法中支持 TLV 序列格式,因此我不必对签名过程来实现我想要的。虽然我只假设这个枚举是答案中描述的 TLV 序列,因为它使用不同的 RFC 或 IEEE 规范来引用它。尽管如此,它还是解决了我的问题。 (我还在驱动器 sample_signed_ecdsa_Rfc3279DerSequence.pdf
和相应的响应 JSON
中添加了一个新的 pdf。)可能默认情况下它使用 DSASignatureFormat.IeeeP1363FixedFieldConcatenation
,因为指定该参数不会更改签名有效性,但指定另一个参数使其在 iText 7 中也有效。
现在关于互操作性,我不确定如何更改我的代码以使用 IExternalSignatureContainer
。我是这个数字签名的新手,我只关注了他们网站上的 iText 5 书和更新的 iText 7 示例,不幸的是,除了 API 引用之外,我无法找到关于它的示例或文档。
最佳答案
您的 ECDSA 签名中存在仅被 Adobe Acrobat 而不是 iText 7 忽略的问题。
有两种主要的 ECDSA 签名值编码格式:
作为两个 INTEGER
值的 TLV SEQUENCE
ECDSA-Sig-Value ::= SEQUENCE {
r INTEGER,
s INTEGER
}
(请参阅 ANSI X9.62、RFC 5480 和 SEC 1: Elliptic Curve Cryptography,在 SECG 文档中由两个额外的可选值扩展);
作为两个具有固定长度的整数的串联(参见 BSI TR-03111 ),也称为纯格式。
要使用的格式取决于应用的签名算法。例如:
SEQUENCE
格式。不幸的是,您的 ECDSA CMS 签名容器 SignerInfo 对象的 OID 为 1.2.840.10045.2.1,签名算法应该在该位置;并且该 OID 仅仅是 ECDSA 公钥的 OID,根本不是特定的算法标识符。在不同的验证器中,这有不同的效果:
因此,如果您只需要您的签名被Adobe Acrobat 和iText 7 接受,那么确保ECDSA 签名值是TLV 格式就足够了。
另一方面,如果您希望签名具有更高的互操作性,请更改基于 iText 7 的签名代码以使用 IExternalSignatureContainer
实现(不是 IExternalSignature
一)你在其中构建一个正确的 CMS 签名容器。当心,iText 中的 ECDSA 支持是有限的;特别是,您必须使用隐含 TLV 格式的签名算法。
关于c# - ECDSA 签名的 PDF 无法通过 iText 7 (C#) 进行签名验证,但通过 Adobe Reader DC 成功,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67214674/
在 JSF2 应用程序中遇到验证属性的问题时,有两种主要方法。 使用 Annotation 在 ManagedBean 上定义验证 @ManagedBean public class MyBean {
我想实现一个不常见的功能,我认为 jquery 验证插件将是最好的方法(如果您在没有插件的情况下建议和回答,我们也会欢迎)。我想在用户在输入字段中输入正确的单词后立即隐藏表单。我试过这个: $("
我有几个下拉菜单(类名为month_dropdown),并且下拉菜单的数量不是恒定的。我怎样才能为它们实现 NotEqual 验证。我正在使用 jQuery 验证插件。 这就是我写的 - jQuery
我设法制作了这个网址验证代码并且它起作用了。但我面临着一个问题。我认为 stackoverflow 是获得解决方案的最佳场所。 function url_followers(){ var url=do
我目前正在使用后端服务,该服务允许用户在客户端应用程序上使用 Google Games 库登录。 用户可以通过他们的 gplay ID 向我们发送信息,以便登录或恢复旧帐户。用户向我们发送以下内容,包
我正在尝试验证输入以查看它是否是有效的 IP 地址(可能是部分地址)。 可接受的输入:172、172.112、172.112.113、172.112.113.114 Not Acceptable 输入
我从 Mongoose 验证中得到这条消息: 'Validator failed for path phone with value ``' 这不应该发生,因为不需要电话。 这是我的模型架构: var
我一直在尝试使用Python-LDAP (版本 2.4.19)在 MacOS X 10.9.5 和 Python 2.7.9 下 我想在调用 .start_tls_s() 后验证与给定 LDAP 服务
我正在处理一个仅与 IE6 兼容的旧 javascript 项目(抱歉...),我想仅在 VS 2017 中禁用此项目的 ESLint/CSLint/Javascript 验证/CSS 验证。 我知道
我正在寻找一种方法来验证 Spring 命令 bean 中的 java.lang.Double 字段的最大值和最小值(一个值必须位于给定的值范围之间),例如, public final class W
我正在尝试在 springfuse(JavaEE 6 + Spring Framework (针对 Jetty、Tomcat、JBoss 等)) 和 maven 的帮助下构建我的 webapps 工作
我试图在我们的项目中使用 scalaz 验证,但遇到了以下情况: def rate(username: String, params: Map[String, String]): Validation
我有一个像这样的 Yaml 文件 name: hhh_aaa_bbb arguments: - !argument name: inputsss des
我有一个表单,人们可以单击并向表单添加字段,并且我需要让它在单击时验证这些字段中的值。 假设我单击它两次并获取 2 个独立的字段集,我需要旋转 % 以确保它在保存时等于 100。 我已放入此函数以使其
在我的页面中有一个选项可以创建新的日期字段输入框。用户可以根据需要创建尽可能多的“截止日期”和“起始日期”框。就像, 日期_to1 || date_from1 日期到2 ||日期_from2 date
我有一个像这样的 Yaml 文件 name: hhh_aaa_bbb arguments: - !argument name: inputsss des
有没有办法在动态字段上使用 jquery 验证表单。 我想将其设置为必填字段 我正在使用 Jsp 动态创建表单字段。 喜欢 等等...... 我想使用必需的表单字段验证此表单字段。 最佳答
嗨,任何人都可以通过提供 JavaScript 代码来帮助我验证用户名文本框不应包含数字,它只能包含一个字符。 最佳答案 使用正则表达式: (\d)+ 如果找到匹配项,则字符串中就有一个数字。 关于J
我有两个输入字段holidayDate和Description(id=tags) $(document).ready(function() {
我遇到了这个问题,这些验证从电子邮件验证部分开始就停止工作。 我只是不明白为什么即使经过几天的观察,只是想知道是否有人可以在这里指出我的错误? Javascript部分: function valid
我是一名优秀的程序员,十分优秀!