C#中使用iText7签名PDF遇Pkcs12Store命名空间冲突问题
解决iText7签名时BouncyCastle类型冲突问题
问题描述
使用C#版本的iText7(8.0.2)对PDF签名时,创建Org.BouncyCastle.Pkcs.Pkcs12Store实例时触发编译错误:
The type 'Pkcs12Store' exists in both 'BouncyCastle.Crypto, Version=1.9.0.0, Culture=neutral, PublicKeyToken=0e99375e54769942' and 'BouncyCastle.Cryptography, Version=2.0.0.0, Culture=neutral, PublicKeyToken=072edcf4a5328938'
已安装同版本的itext7.bouncy-castle-adapter包,排查多篇帖子未解决。
错误原因
iText7 8.x版本适配的是BouncyCastle.Cryptography 2.x版本(新命名空间的包),但项目中同时引用了旧版的BouncyCastle.Crypto(1.9.x),导致类型重复定义冲突。
修复步骤
1. 清理重复的BouncyCastle引用
- 打开项目的NuGet包管理器,卸载所有旧版
BouncyCastle.Crypto相关包 - 确保只保留
BouncyCastle.Cryptography(2.x版本)和itext7.bouncy-castle-adapter(8.0.2)
2. 调整代码命名空间引用
iText7的BouncyCastle适配器已封装对BouncyCastle的调用,建议直接使用iText提供的封装类,避免直接引用Org.BouncyCastle命名空间,修改后的代码如下:
using iText.Kernel.Pdf; using iText.Signatures; using iText.Bouncycastle.Cert; using iText.Bouncycastle.Crypto; using iText.Commons.Bouncycastle.Cert; using iText.IO.Font.Constants; using iText.Kernel.Font; using iText.Kernel.Geom; using System.IO; // 移除直接引用Org.BouncyCastle的命名空间 PdfReader pdfReader = new PdfReader(input); IExternalSignature _privateSignature; IX509Certificate[] _signChain; string KEYSTORE = @""; char[] PASSWORD = "".ToCharArray(); // 使用iText封装的Pkcs12Store替代原生类 var pks = new iText.Bouncycastle.Pkcs.Pkcs12StoreBC(new FileStream(KEYSTORE, FileMode.Open, FileAccess.Read), PASSWORD); string alias = null; foreach (string tAlias in pks.GetAliases()) { if (pks.IsKeyEntry(tAlias)) { alias = tAlias; break; } } var pk = pks.GetKey(alias).GetPrivateKey(); var ce = pks.GetCertificateChain(alias); _signChain = new IX509Certificate[ce.Length]; for (int k = 0; k < ce.Length; ++k) { _signChain[k] = new X509CertificateBC(ce[k].GetCertificate()); } _privateSignature = new PrivateKeySignature(new PrivateKeyBC(pk), "SHA-512"); using (FileStream signedPdf = new FileStream(output, FileMode.Create, FileAccess.ReadWrite)) { StampingProperties properties = new StampingProperties(); var signer = new iText.Signatures.PdfSigner(pdfReader, signedPdf, properties.UseAppendMode()); PdfSignatureAppearance sap = signer.GetSignatureAppearance(); sap.SetLayer2Text(string.Empty); sap.SetPageNumber(pageNumber); sap.SetLayer2Text(DateTime.Now.ToString()); sap.SetRenderingMode(PdfSignatureAppearance.RenderingMode.NAME_AND_DESCRIPTION); sap.SetLayer2FontSize(7); sap.SetPageRect(new iText.Kernel.Geom.Rectangle(50, 700, 200, 100)); PdfFont font = PdfFontFactory.CreateFont(StandardFonts.HELVETICA); sap.SetLayer2Font(font); signer.SignDetached(_privateSignature, _signChain, null, null, null, 0, iText.Signatures.PdfSigner.CryptoStandard.CMS); }
3. 程序集绑定重定向(可选)
如果仍有冲突,可在项目的app.config或web.config中添加绑定重定向,强制使用新版BouncyCastle:
<runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="BouncyCastle.Cryptography" publicKeyToken="072edcf4a5328938" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="BouncyCastle.Crypto" publicKeyToken="0e99375e54769942" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-1.9.0.0" newVersion="2.0.0.0" /> </dependentAssembly> </assemblyBinding> </runtime>
关键说明
- iText7 8.x版本不再支持旧版
BouncyCastle.Crypto,必须使用BouncyCastle.Cryptography2.x系列包 - 优先使用iText提供的
iText.Bouncycastle命名空间下的封装类,避免直接操作Org.BouncyCastle原生类型,减少版本冲突风险
内容的提问来源于stack exchange,提问作者Anki
相关产品推荐
相关产品推荐

