我正在c#中开发一个执行数字签名验证的网络服务器,以确保不修改pdf文件。 我正在使用iText和iTextSharp。
但客户端基于java applet。我在那个java applet中执行数字签名。在java中我能够制作签名然后验证它们。但是,如果我在C#中验证签名,则会给出nullreferenceexception。
这是我的Java数字签名代码:
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;
}
}
在行af.VerifySignature(姓名);抛出NullReferenceException!
有趣的是,如果我使用C#代码执行签名,我可以在java中验证它,因为我添加了以下指令: BouncyCastleProvider provider = new BouncyCastleProvider(); Security.addProvider(提供商);
我认为我的问题依赖于一些字节转换......但在C#中我不知道如何调用bouncycastleprovider。
你能帮帮我吗? 我最诚挚的问候:威廉。答案 0 :(得分:1)
OP在评论中发布的堆栈跟踪
...
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 {{1}已经重构为名称空间PdfPKCS7
。
此重构是整个iText签名创建和验证代码的重大更新的一部分,这一更新引入了许多新功能。
因此,建议OP更新iTextSharp程序集,确实:
我下载了最新的itextsharp版本,并且验证效果很好。