当前位置: 首页 > 知识库问答 >
问题:

数字签名验证与文本不工作

翁良弼
2023-03-14

我使用itext库来验证数字签名的pdf,下面的例子可以在https://developers.itextpdf.com/examples/security/digital-signatures-white-paper/digital-signatures-chapter-5地点我在验证数字签名文档时遇到以下错误。谁能帮忙解决这个问题。

Exception in thread "main" ExceptionConverter: java.security.NoSuchAlgorithmException: SHA256with1.2.840.10045.4.3.2 Signature not available
at java.security.Signature.getInstance(Signature.java:229)
at com.itextpdf.text.pdf.security.PdfPKCS7.initSignature(PdfPKCS7.java:697)
at com.itextpdf.text.pdf.security.PdfPKCS7.<init>(PdfPKCS7.java:459)
at com.itextpdf.text.pdf.AcroFields.verifySignature(AcroFields.java:2420)
at com.itextpdf.text.pdf.AcroFields.verifySignature(AcroFields.java:2373)
at nic.test.C5_01_SignatureIntegrity.verifySignature(C5_01_SignatureIntegrity.java:24)
at test.ExtractSignInfor.inspectSignature(ExtractSignInfor.java:95)
at test.ExtractSignInfor.inspectSignatures(ExtractSignInfor.java:135)
at test.ExtractSignInfor.main(ExtractSignInfor.java:63)

共有2个答案

通煜祺
2023-03-14

正如米夏埃尔·德米在他的回答中已经解释的那样,这是第5条。x目前不支持所讨论的算法OID。

幸运的是,iText 5. x在签名验证期间主要依赖底层的BouncyCastle库来支持安全算法,并且本身只做很少的工作,所缺少的是iText正确地找到OID的“加密算法”ECDSA的名称(引号,因为它不是真正的加密,因为没有并行解密)。

您可以在iText 5. x中添加该OID的验证支持(在5.5.13的当前SNAPSHOT中测试),如下所示:

java.lang.reflect.Field algorithmNamesField = com.itextpdf.text.pdf.security.EncryptionAlgorithms.class.getDeclaredField("algorithmNames");
algorithmNamesField.setAccessible(true);
@SuppressWarnings("unchecked")
HashMap<String, String> algorithmNames = (HashMap<String, String>) algorithmNamesField.get(null);
algorithmNames.put("1.2.840.10045.4.3.2", "ECDSA");

执行此添加后,iText验证

PdfReader reader = new PdfReader(resource);
AcroFields acroFields = reader.getAcroFields();

List<String> names = acroFields.getSignatureNames();
for (String name : names) {
   System.out.println("Signature name: " + name);
   System.out.println("Signature covers whole document: " + acroFields.signatureCoversWholeDocument(name));
   System.out.println("Document revision: " + acroFields.getRevision(name) + " of " + acroFields.getTotalRevisions());
   PdfPKCS7 pk = acroFields.verifySignature(name);
   System.out.println("Subject: " + CertificateInfo.getSubjectFields(pk.getSigningCertificate()));
   System.out.println("Document verifies: " + pk.verify());
}

显示

Signature name: Signature1
Signature covers whole document: true
Document revision: 1 of 1
Subject: {ST=[Rajasthan], C=[India], CN=[Devi Singh Pilwal], O=[Personal]}
Document verifies: true

(VerifySignature.java方法中的测试代码testVerifyTestDsp

>

  • 上面的代码使用反射,因为有问题的Map不是公开的。根据您的环境,这样的html" target="_blank">解决方案可能不被允许。在这种情况下,您必须相应地修补iText。此外,由于访问的Map不是公开的,解决方案可能在未来的版本中失败。(这不太可能,因为iText 5处于维护模式,但谁也不知道。)

    这只会增加对这个非常复杂的问题的支持。类似地,也可以添加对许多其他OID的支持,但不一定对所有OID都支持。

    此外,我只在一个验证用例中测试了这一点。ECDSA签名可能需要完全不同的更改。

  • 章兴发
    2023-03-14

    如果搜索iText阻塞的OID,您将看到这是“ecdsa-with-sha256”:

    http://www.oid-info.com/get/1.2.840.10045.4.3.2

    这在iText 5中不受支持。但是我们在iText 7中添加了对它的支持。尝试使用最新的iText 7版本运行此代码示例:

    BouncyCastleProvider provider = new BouncyCastleProvider();
    Security.addProvider(provider);
    
    PdfReader reader = new PdfReader(INPUT);
    PdfDocument pdfDocument = new PdfDocument(reader);
    
    PdfAcroForm acroForm = PdfAcroForm.getAcroForm(pdfDocument, false);
    
    for ( String name : acroForm.getFormFields().keySet() ) {
        PdfFormField formField = acroForm.getField(name);
        if (formField != null && formField instanceof PdfSignatureFormField)    {
            SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
            PdfPKCS7 pkcs7 = signatureUtil.verifySignature(name);
            pkcs7.verify();
            [...]
    
     类似资料:
    • 我有字节数组格式的公钥。在我的数据库里。像这样 在此处输入图像描述 总是suc=false。我确信bytetoverify的值与方法符号中的输入值相同。 我不知道我用这种方式生成公钥是问题还是符号有问题。在符号方法中,我使用sh1和pkcs1,但在验证中,我只找到sh1。 每个人都能帮我吗?

    • 在我的应用程序中,我有一个公钥(表示为字符串),普通消息和数字签名,表示为base64编码字符串,用SHA256散列,用RSA加密)。现在,我需要验证数字签名。我试图做如下操作: 从创建(取自此处) 根据原始消息创建SHA256摘要 使用函数验证签名 (我正在努力避免使用OpenSSL函数) 此外,我的数字签名是使用Java的SHA256withRSA方法创建的。我在这里读到SHA256WithR

    • 我的手被https、ssl、PKI之类的东西弄得脏兮兮的。对于自签名证书,有一点我不太理解。假设我想创建一个自签名证书,并在我们想要建立安全连接时将其发送给我的朋友。 所以步骤是: 创建一个私钥。 创建一个公钥。 用我的公钥在证书上签名。 因此,当我的朋友得到我的证书时,他必须验证他得到的证书是我的,他需要解密数字签名。但为了解密和验证他必须拥有我的私钥。所以,我有点困惑。

    • 下面是我的场景--我从条形码中读取数据,并将其转换为纯文本。本文是条码数据+数字签名的结合。数字签名附加在末尾,使我能够分离出实际数据和数字签名数据。数字签名数据使用sha256哈希-用户将公钥作为windows证书文件()发送给我。 所需实现:-需要从证书中提取公钥,并根据提供的条形码数据和数字签名验证公钥。 问题:

    • 我有一个电子签名/数字签名的PDF,该文档在分离签名中使用iText lib进行签名。我在验证签名时遇到问题,收到消息“签名者身份无效,因为它已过期或尚未有效”,并且在签名者信息中“构建从签名者证书到颁发者证书的路径时出错。” 我尝试了很多方法来验证签名,但都没有成功。如果我明确地将签名者证书添加为可信证书,那么我会得到一个绿色检查,并能够验证签名,但我认为这不是正确的方法。 数字签名的pdf可以

    • 我在iText web上遵循了这个示例(http://gitlab.itextsupport.com/itextsharp/tutorial/blob/master/signatures/chapter5/C5_03_CertificateValidation/C5_03_CertificateValidation.cs),但结果与我预期的不一样。具体地说,当试图通过OCSP或CRL验证签名时,结