我已经使用ECDSA(SHA-256)证书用iText 8.0.2签署了一个PDF文档.不幸的是,Adobe Reader说签名无效,理由是"Document has been altered or corrupted since it was signed".由于数字签名主题不是我的专长,我不知道如何查找错误以及在哪里查找错误.有谁能给我带路吗?
using iText.Kernel.Pdf;
using iText.Signatures;
using System;
using System.IO;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
namespace PdfSignTest
{
class Program
{
static void Main(string[] args)
{
if (args.Length < 2)
{
Console.WriteLine("Usage: PdfSignTest.exe pdfFilePath pfxFilePath");
Console.WriteLine(" - pdfFilePath: path of an unsigned pdf file which will be signed");
Console.WriteLine(" - pfxFilePath: path of a pfx file containing the full certificate chain");
Console.ReadKey();
return;
}
string srcPath = args[0];
string cerPath = args[1];
string dstPath = srcPath.Replace(".pdf", ".signed.at." + DateTime.Now.ToString("HH-mm-ss") + ".pdf");
var signed = SignPdfECC(srcPath, cerPath);
File.WriteAllBytes(dstPath, signed);
Console.WriteLine(string.Format("File {0} successfully signed and saved as {1}.", srcPath, dstPath));
Console.ReadKey();
}
private static byte[] SignPdfECC(string unsignedPdfPath, string certificatePfxPath)
{
byte[] certificatePfx = File.ReadAllBytes(certificatePfxPath);
using (PdfReader reader = new PdfReader(unsignedPdfPath))
using (MemoryStream mem = new MemoryStream())
{
PdfSigner signer = new PdfSigner(reader, mem, new StampingProperties().UseAppendMode());
X509Certificate cert = new X509Certificate(certificatePfx, "password", X509KeyStorageFlags.Exportable);
X509Certificate2 signatureCert = new X509Certificate2(cert);
ECDsa pk = signatureCert.GetECDsaPrivateKey();
IExternalSignature signature = new EcdsaSignature(pk, Digest算法rithms.SHA256);
iText.Bouncycastle.X509.X509CertificateBC[] chain = new iText.Bouncycastle.X509.X509CertificateBC[] { new iText.Bouncycastle.X509.X509CertificateBC(new Org.BouncyCastle.X509.X509Certificate(signatureCert.GetRawCertData())) };
signer.SignDetached(signature, chain, null, null, null, 0, PdfSigner.CryptoStandard.CMS);
return mem.ToArray();
}
}
}
public class EcdsaSignature : IExternalSignature
{
private readonly string _encryption算法rithm;
private readonly string _hash算法rithm;
private readonly ECDsa _pk;
public EcdsaSignature(ECDsa pk, string hash算法rithm)
{
_pk = pk;
_hash算法rithm = Digest算法rithms.GetDigest(Digest算法rithms.GetAllowedDigest(hash算法rithm));
_encryption算法rithm = "ECDSA";
}
public string GetDigest算法rithmName()
{
return "SHA-256";
}
public virtual string GetEncryption算法rithm()
{
return _encryption算法rithm;
}
public virtual string GetHash算法rithm()
{
return _hash算法rithm;
}
public string GetSignature算法rithmName()
{
return "ECDSA";
}
public ISignatureMechanismParams GetSignatureMechanismParameters()
{
return null;
}
public virtual byte[] Sign(byte[] message)
{
return _pk.SignData(message, new Hash算法rithmName(_hash算法rithm));
}
}
}
我删除了所有其他功能,如TSA和LTV,以为可能是这些步骤中的一个导致了错误.我还try 使用从OpenSSL测试证书集合中获取的测试证书,以及从w3.org下载的测试PDF.所有这些都是here.