过去几年我们使用 iText7 版本 7.X dotnet 对 PDF 进行数字签名。
它工作得很好(现在仍然如此),但 iText7 发布了一个新版本(名称有点令人困惑的版本 8),它与我们的代码不兼容。
似乎无法找到有关如何签署 PDF 的版本 8 的任何更新示例。
这是我们正在使用的代码:
public class PdfSigner
{
IExternalSignature _privateSignature;
X509Certificate[] _signChain;
public PdfSigner(Stream privateKeyStream, string keyPassword)
{
var pks = new Pkcs12Store(privateKeyStream, keyPassword.ToCharArray());
string alias = null;
foreach (string tAlias in pks.Aliases)
{
if (pks.IsKeyEntry(tAlias))
{
alias = tAlias;
break;
}
}
var pk = pks.GetKey(alias).Key;
var ce = pks.GetCertificateChain(alias);
_signChain = new X509Certificate[ce.Length];
for (int k = 0; k < ce.Length; ++k)
_signChain[k] = ce[k].Certificate;
_privateSignature = new PrivateKeySignature(pk, "SHA-512");
}
public void SignPDF(Stream input, Stream output, PDFSignParameters p)
{
PdfReader reader = new PdfReader(input);
StampingProperties properties = new StampingProperties();
var signer = new iText.Signatures.PdfSigner(reader, output, properties);
PdfSignatureAppearance sap = signer.GetSignatureAppearance().SetReason(p.Reason).SetLocation(p.Location);
if (p.Image != null)
{
var img = iText.IO.Image.ImageDataFactory.Create(new BinaryReader(p.Image.Data).ReadBytes((int)p.Image.Data.Length));
sap.SetSignatureGraphic(img);
sap.SetLayer2Text(string.Empty);
sap.SetPageRect(new iText.Kernel.Geom.Rectangle(p.Image.X, p.Image.Y, img.GetWidth() / p.Image.WidthRatio, img.GetHeight() / p.Image.HeigthRatio));
sap.SetImage(img);
}
signer.SignDetached(_privateSignature, _signChain, null, null, null, 0, iText.Signatures.PdfSigner.CryptoStandard.CMS);
}
}
代码有 2 个编译器错误
1.构造函数的最后一行
_privateSignature = new PrivateKeySignature(pk, "SHA-512");
错误是(pk参数)
cannot convert from 'Org.BouncyCastle.Crypto.AsymmetricKeyParameter' to 'iText.Commons.Bouncycastle.Crypto.IPrivateKey'
2.SignPDF方法的最后一行
signer.SignDetached(_privateSignature, _signChain, null, null, null, 0, iText.Signatures.PdfSigner.CryptoStandard.CMS);
错误是(_signChain参数)
cannot convert from 'Org.BouncyCastle.X509.X509Certificate[]' to 'iText.Commons.Bouncycastle.Cert.IX509Certificate[]'
我确实找不到任何有关如何更新代码的文档或版本 8 的全新代码的新相关示例。
提前致谢。
@andre,感谢您的链接,在几个搜索引擎上通过关键字搜索没有找到它。
我还必须向我的项目添加另一个 nuget 包,名为“itext7.bouncy-castle-adapter”
这是我在 Itext7 版本 8.x 上的工作代码:
public class PdfSigner
{
IExternalSignature _privateSignature;
IX509Certificate[] _signChain;
public PdfSigner(Stream privateKeyStream, string keyPassword)
{
var pks = new Pkcs12Store(privateKeyStream, keyPassword.ToCharArray());
string alias = null;
foreach (string tAlias in pks.Aliases)
{
if (pks.IsKeyEntry(tAlias))
{
alias = tAlias;
break;
}
}
var pk = pks.GetKey(alias).Key;
var ce = pks.GetCertificateChain(alias);
_signChain = new IX509Certificate[ce.Length];
for (int k = 0; k < ce.Length; ++k)
_signChain[k] = new X509CertificateBC(ce[k].Certificate);
_privateSignature = new PrivateKeySignature(new PrivateKeyBC(pk), "SHA-512");
}
public void SignPDF(Stream input, Stream output, PDFSignParameters p)
{
PdfReader reader = new PdfReader(input);
StampingProperties properties = new StampingProperties();
var signer = new iText.Signatures.PdfSigner(reader, output, properties);
PdfSignatureAppearance sap = signer.GetSignatureAppearance().SetReason(p.Reason).SetLocation(p.Location);
if (p.Image != null)
{
var img = iText.IO.Image.ImageDataFactory.Create(new BinaryReader(p.Image.Data).ReadBytes((int)p.Image.Data.Length));
sap.SetSignatureGraphic(img);
sap.SetLayer2Text(string.Empty);
sap.SetPageRect(new iText.Kernel.Geom.Rectangle(p.Image.X, p.Image.Y, img.GetWidth() / p.Image.WidthRatio, img.GetHeight() / p.Image.HeigthRatio));
sap.SetImage(img);
}
signer.SignDetached(_privateSignature, _signChain, null, null, null, 0, iText.Signatures.PdfSigner.CryptoStandard.CMS);
}
}
我希望它对未来的其他人有帮助。