我正在使用ItextSharp将数字签名应用于PDF文件。使用下面的代码,我可以将签名应用于也能够验证签名的PDF文件,但PDF文件的签名框中缺少签名验证标记。
iTextSharp-(Runtime version = v2.0.50727) (Version = 5.5.10.0)
using Org.BouncyCastle.Pkcs;
using System.IO;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.security;
public class DigitalSignaturePDF
{
public void DigiSignPdf(string sourceDocument,
string destinationPath,
Stream privateKeyStream,
string keyPassword,
string reason,
string location,
bool isVisibleSignature)
{
Pkcs12Store pk12 = new Pkcs12Store(privateKeyStream, keyPassword.ToCharArray());
privateKeyStream.Dispose();
//then Iterate throught certificate entries to find the private key entry
string alias = null;
foreach (string tAlias in pk12.Aliases)
{
if (pk12.IsKeyEntry(tAlias))
{
alias = tAlias;
break;
}
}
var pk = pk12.GetKey(alias).Key;
// reader and stamper
PdfReader reader = new PdfReader(sourceDocument);
using (FileStream fout = new FileStream(destinationPath, FileMode.Append, FileAccess.Write))
{
using (PdfStamper stamper = PdfStamper.CreateSignature(reader, fout, '\0'))
{
// appearance
PdfSignatureAppearance appearance = stamper.SignatureAppearance;
//appearance.Image = new iTextSharp.text.pdf.PdfImage();
appearance.Reason = reason;
appearance.Location = location;
if (isVisibleSignature)
{
appearance.SetVisibleSignature(new iTextSharp.text.Rectangle(20, 10, 170, 60), reader.NumberOfPages, null);
}
//Get all certificate for validation
X509CertificateEntry[] ce = pk12.GetCertificateChain(alias);
Org.BouncyCastle.X509.X509Certificate[] chain;
chain = new Org.BouncyCastle.X509.X509Certificate[ce.Length];
for (int k = 0; k < ce.Length; ++k)
{
chain[k] = ce[k].Certificate;
}
// digital signature
IExternalSignature es = new PrivateKeySignature(pk, "SHA-256");
MakeSignature.SignDetached(appearance, es, chain, null, null, null, 0, CryptoStandard.CMS);
stamper.Close();
}
}
reader.Close();
reader.Dispose();
}
}
如上图所示,签名框中缺少验证标记。
但是当我使用下面的代码尝试使用旧版本的ItextSharp时,如果签名有效则显示绿色标记,如果签名无效则显示黄色问号。
iTextSharp-(Runtime version = v1.1.4322) (Version = 3.1.0.0)
public void Sign(string SigReason, string SigContact, string SigLocation, bool visible)
{
PdfReader reader = new PdfReader(this.inputPDF);
PdfStamper st = PdfStamper.CreateSignature(reader, new FileStream(this.outputPDF, FileMode.Create, FileAccess.Write), '\0', null, true);
PdfSignatureAppearance sap = st.SignatureAppearance;
sap.SetCrypto(this.myCert.Akp, this.myCert.Chain, null, PdfSignatureAppearance.SELF_SIGNED);
sap.Reason = SigReason;
sap.Contact = SigContact;
sap.Location = SigLocation;
sap.SetVisibleSignature(new iTextSharp.text.Rectangle(100, 100, 25, 15), 1, null);
st.Close();
}
在上图中,绿色标记附有签名框,表明签名有效。
当我使用iTextSharp 5.5.10.0
时,任何人都知道为什么缺少验证tic,我在这里缺少什么。
答案 0 :(得分:0)
您要求的东西违反了最新标准。请允许我引用PAdES-6又名ETSI TS 102 778-6 V1.1.1(参见第6章的介绍):
符合标识的处理程序不得显示结果 页面内容中的签名验证。
注意:符合标识的处理程序将使用离页显示来显示 验证结果
粗体字在PAdES-6标准中也是粗体。当官方标准使用&#34;不应该&#34;时,规范告诉您不应该做某事,但如果您这样做,则不违反标准。但是,当官方标准使用“&#34;”时,不得&#34 ;;规范告诉你,你不能做某事,因为如果你做了,你违反了标准。
简而言之:您以前使用iTextSharp 3.1.0.0创建的签名不再符合签名。许多年前,他们没事,但今天,这些签名不再有效。我们已经警告过使用旧的iText和iTextSharp版本多次签署PDF文档(参见Are PDF Signatures shattered?)。
现在看来,您现在需要一个与当前标准(PAdES和ISO-32000-2)同步的iTextSharp版本来创建根据相同标准无效的签名。我希望你明白这是完全错误的。
我也希望您了解您的共享代码iTextSharp 3.1.0.0示例创建了一个使用弃用算法的签名。如果该代码仍在使用中,您应该告知您的客户他使用该代码签署的所有文件都不再安全。