问题描述
我需要对PDF文档进行数字签名。要签名,我需要将摘要发送到另一个Web服务。
Firs步骤是创建带有空签名的新PDF文件。之后,我需要提取该文件的摘要,然后将其发送到Web服务进行签名。
public static string GetBytesToSign(string unsignedPdf,string tempPdf,string signatureFieldName)
{
if (File.Exists(tempPdf))
File.Delete(tempPdf);
using (PdfReader reader = new PdfReader(unsignedPdf))
{
using (FileStream os = File.OpenWrite(tempPdf))
{
StampingProperties sp = new StampingProperties();
sp.UseAppendMode();
PdfSigner pdfSigner = new PdfSigner(reader,os,sp);
pdfSigner.SetFieldName(signatureFieldName);
PdfSignatureAppearance appearance = pdfSigner.GetSignatureAppearance();
appearance.SetPageNumber(1);
appearance.SetPageRect(new Rectangle(100,100));
appearance.SetLocation("Varazdin");
//Creating container for emty signature,with atrivute where digest is calculated.
//ExternalHashingSignatureContainer external = new ExternalHashingSignatureContainer(PdfName.Adobe_PPKLite,PdfName.Adbe_pkcs7_detached);
//pdfSigner.SignExternalContainer(external,8192);
//hash = external.Hash;
//Creating container for empty signature.
IExternalSignatureContainer external = new ExternalBlankSignatureContainer(PdfName.Adobe_PPKLite,PdfName.Adbe_x509_rsa_sha1);
pdfSigner.SignExternalContainer(external,8192);
//Digest from created new temporary PDF with empty space for signature.
FileStream oso = File.OpenRead(temp);
hash = DigestAlgorithms.Digest(oso,DigestAlgorithms.SHA256);
return Convert.ToBase64String(hash);
}
}
}
然后Web服务发送此签名:
T0Am92hjg5Q+CrMdrq8hQEiJ80UUyBWyAeo0JQoLGSq0LdK/ZhZB2Mk9feCiohiDpA5Qyp2TCoa2FWbk6jK48ajAHKxmEc5wO4Niv2DlaWh8fv2lBj+OxpVrUDm7Y26o4ITQzC8VECLNHE6jQL7O6VCmCdhaOrSpnvHaCZctrFfrxWlTT4d6tQBtR/Znp/eam4PxQtoUxYkan8FYxxMacfOm3hEPdUJ2Wp2chiWDou4bn+Mc6JERLqErmZcNrzASifiuvMn5padc/qNN71tJYCi1XlAgzrWgZqShgRTNxXD8CBbJD+2vCGkLJlrEuiCqyvMeFNc911zw/Ln1P8ZCDw==
然后我尝试将该签名添加到带有空签名的临时pdf文件中。我使用以下代码:
public static void EmbedSignature(string tempPdf,string signedPdf,string signatureFieldName,string signature,string tbs)
{
//Convert given data from web service to bytes
byte[] signedBytes = ConvertToBytes(signature);
byte[] toBeSigned = ConvertToBytes(tbs);
using (PdfReader reader = new PdfReader(tempPdf))
{
using (FileStream os = File.OpenWrite(signedPdf))
{
PdfSigner signer = new PdfSigner(reader,new StampingProperties());
IExternalSignatureContainer external = new MyExternalSignatureContainer(signedBytes,GetChains(),toBeSigned);
PdfSigner.SignDeferred(signer.GetDocument(),signatureFieldName,external);
}
}
}
class MyExternalSignatureContainer : IExternalSignatureContainer
{
protected X509Certificate[] chain;
protected byte[] signedHash;
protected byte[] hash;
public MyExternalSignatureContainer(byte[] signedHash,X509Certificate[] chain,byte[] hash)
{
this.signedHash = signedHash;
this.chain = chain;
this.hash = hash;
}
public byte[] Sign(Stream inputStream)
{
try
{
String hashAlgorithm = DigestAlgorithms.SHA256;
PdfPKCS7 sgn = new PdfPKCS7(null,chain,hashAlgorithm,false);
sgn.SetExternalDigest(signedHash,null,"RSA");
return sgn.GetEncodedPKCS7(hash,PdfSigner.CryptoStandard.CMS,null);
}
catch (IOException ioe)
{
throw new Exception(ioe.Message);
}
}
public void ModifySigningDictionary(PdfDictionary signDic)
{
}
}
此后,所有消息均已成功导入,但在Adobe Reader中是此消息:
文档签名后被更改或损坏。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)