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

java中的PDF数字签名和C#(iText)中的签名验证

钦良弼
2023-03-14

我正在用C#开发一个执行数字签名验证的webserver,以确保pdf文件没有被修改。我使用了iText和iTextSharp。

           String path = "C:/Users/a/Desktop/cert.pfx";
    String keystore_password = "fgf";
    String key_password = "fgf";

    ////

    BouncyCastleProvider provider = new BouncyCastleProvider();
    Security.addProvider(provider);


    KeyStore ks = KeyStore.getInstance("pkcs12", "BC");
    ks.load(new FileInputStream(path), keystore_password.toCharArray());

    String alias = (String)ks.aliases().nextElement();

    PrivateKey pk = (PrivateKey) ks.getKey(alias, key_password.toCharArray());

    Certificate[] chain = ks.getCertificateChain(alias);

            PdfReader reader = new PdfReader(src);
    dest = "C:/Users/a/Desktop/" + dest;
    FileOutputStream os = new FileOutputStream(dest);
    PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');

    PdfSignatureAppearance appearance = stamper.getSignatureAppearance();


    ExternalSignature es = new PrivateKeySignature(pk, "SHA-256", "BC");
    ExternalDigest digest = new BouncyCastleDigest();

    MakeSignature.signDetached(appearance, digest, es, chain, null, null, null, 0, CryptoStandard.CMS);

和我的C#验证码:

             PdfReader reader = new PdfReader(pdfFile);
            AcroFields af = reader.AcroFields;
            var names = af.GetSignatureNames();

            if (names.Count == 0)
            {
                throw new InvalidOperationException("No Signature present in pdf file.");
            }


            foreach (string name in names)
            {
                if (!af.SignatureCoversWholeDocument(name))
                {
                    throw new InvalidOperationException(string.Format("The signature: {0} does not covers the whole document.", name));
                }


                PdfPKCS7 pk = af.VerifySignature(name);
                var cal = pk.SignDate;
                var pkc = pk.Certificates;

                if (!pk.Verify())
                {
                    Console.WriteLine("The signature is not valid.");
                    return false;
                }
             }

在VerifySignature(name)行中;抛出NullReferenceException!

有趣的是,如果我使用C#代码执行签名,我就可以在java中验证它,因为我添加了这些指令:BouncyCastleProvider provider=new BouncyCastleProvider();Security.AddProvider(提供程序);

共有1个答案

沃驰
2023-03-14

操作在注释中发布的stacktrace

...
at org.bouncycastle.security.SignerUtil.getSigner(String algorithm)
at iTextSharp.text.pdf.PdfPKCS7..ctor(Byte[] contentsKey)
at iTextSharp.text.pdf.AcroFields.VerifySignature(String name)
at SignatureLibrary.iText.PDFValidation(String pdfFile)
in ...\\SignatureLibrary\\SignatureLibrary\\iText.cs:line 122

包含行iTextSharp.text.pdf.pdfpkcs7..ctor(Byte[]contentsKey)表示OP使用的不是当前的iTextSharp 5.5.0版本,而是5.3.0之前的版本(2012年6月发布):在5.3.0版本中,pdfpkcs7已重构到名称空间iTextSharp.text.pdf.security中。

这次重构是整个iText签名创建和验证码的主要更新的一部分,该更新引入了许多新特性。

因此,建议OP更新iTextSharp组件,实际上:

我下载了最新的itextsharp版本,它很好地进行了验证。

 类似资料:
  • 我使用PdfWriter setEncryption对PDF文档进行了加密/解密。一切正常,解密也正常。 当我为数字签名的PDF文档做同样的事情时,我的数字信息与消息一起损坏(SigDict/Contents非法数据) 是否可以在不影响数字签名信息的情况下加密PDF?

  • 我需要用c语言验证由JAVA签名API生成的签名。我有一套相同的公钥和私钥。我还验证了c语言的签名和验证工作。但是我在验证JAVA生成的签名时遇到了问题。我看了所有的文件,尝试了不同的方法,但我似乎还是不明白。我将使用用于验证的原始JAVA代码粘贴等效的c代码。 原始JAVA代码: C代码: 我有3个问题: 这是验证签名的正确方法吗? 我需要在验证数据之前对其进行散列吗?如果是,那么JAVA在签名

  • 使用itext v5对文档进行数字签名时。5.11 PDF/A-2b文档被破坏——这意味着它们不再作为PDF/A文档有效。违反以下规则:https://github.com/veraPDF/veraPDF-validation-profiles/wiki/PDFA-Parts-2-and-3-rules#rule-643-1 在上面的链接中,它指定摘要无效,因此我也给你一个代码段,在使用iText

  • 我已经用iText 7创建了代码,它能够用使用ECDSA密钥对的X509证书对给定的PDF进行数字签名。当我在Acrobat Reader DC中打开这个签名的PDF时,它正确地读取它,并验证它是有效的(meaing doc在签名后没有修改,等等)。 但是,当我尝试用iText 7验证同一文档时,完整性和真实性检查返回false。 下面是示例代码: 和从签名中提取的示例输出: 至于互操作性,我不确

  • 我有一个应用程序生成一个PDF,需要签名。 我们没有用于签署文档的证书,因为它们在HSM中,而我们可以使用证书的唯一方法是使用WebService。 这是我们的代码,首先,我们得到签名外观,并计算散列 在这一点上,我们得到一个已签名的PDF,但签名无效。Adobe称“文档自签署以来已被更改或损坏”。 我已经通过使用外部服务和iText,PDF签名iText pkcs7多签名和是否可能签署一个PDF