我是iTextSharp(和StackOverFlow)的新手.我正在尝试使用外部USB令牌在C#中签名PDF.我尝试使用我从互联网上挖掘的以下代码.
Org.BouncyCastle.X509.X509CertificateParser cp = new Org.BouncyCastle.X509.X509CertificateParser(); //Get Sertifiacte X509Certificate2 certClient = null; X509Store st = new X509Store(StoreName.My,StoreLocation.CurrentUser); st.Open(OpenFlags.MaxAllowed); X509Certificate2Collection collection = X509Certificate2UI.SelectFromCollection(st.Certificates,"Please choose certificate:","",X509SelectionFlag.SingleSelection); if (collection.Count > 0){ certClient = collection[0]; } st.Close(); //Get Cert Chain IList<Org.BouncyCastle.X509.X509Certificate> chain = new List<Org.BouncyCastle.X509.X509Certificate>(); X509Chain x509chain = new X509Chain(); x509chain.Build(certClient ); foreach (X509ChainElement x509ChainElement in x509chain.ChainElements){ chain.Add(DotNetUtilities.FromX509Certificate(x509ChainElement.Certificate)); } PdfReader reader = new PdfReader(sourceDocument); FileStream resStream = new FileStream(resultDocument,FileMode.Create,FileAccess.ReadWrite); PdfStamper stamper = PdfStamper.CreateSignature(reader,resStream,'\0',null,true); PdfSignatureAppearance appearance = stamper.SignatureAppearance; appearance.Reason = reason; appearance.Location = location; appearance.SetVisibleSignature(new iTextSharp.text.Rectangle(20,10,170,60),1,"Signed"); X509Certificate2Signature es = new X509Certificate2Signature(certClient,"SHA-1"); MakeSignature.SignDetached(appearance,es,chain,CryptoStandard.CMS);
问题是我收到一个例外:
System.Security.Cryptography.CryptographicException was unhandled Message=Invalid type specified. Source=mscorlib StackTrace: at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr) at System.Security.Cryptography.Utils._GetKeyParameter(SafeKeyHandle hKey,UInt32 paramID) at System.Security.Cryptography.Utils.GetKeyPairHelper(CspAlgorithmType keyType,CspParameters parameters,Boolean randomKeyContainer,Int32 dwKeySize,SafeProvHandle& safeProvHandle,SafeKeyHandle& safeKeyHandle) at System.Security.Cryptography.RSACryptoServiceProvider.GetKeyPair() at System.Security.Cryptography.RSACryptoServiceProvider..ctor(Int32 dwKeySize,Boolean useDefaultKeySize) at System.Security.Cryptography.X509Certificates.X509Certificate2.get_PrivateKey() at iTextSharp.text.pdf.security.X509Certificate2Signature..ctor(X509Certificate2 certificate,String hashAlgorithm) at WindowsFormsApplication1.PDFSignerHelper.signPdfFile(String sourceDocument,String resultDocument,X509Certificate2 certClient,String reason,String location) InnerException:
解决方法
这种方法对我们来说很好(iTextSharp 5.3.3).我们使用智能卡和USB令牌(供应商 –
www.author.kiev.ua):
X509Store store = new X509Store(StoreLocation.CurrentUser); store.Open(OpenFlags.ReadOnly); X509Certificate2Collection sel = X509Certificate2UI.SelectFromCollection(store.Certificates,X509SelectionFlag.SingleSelection); X509Certificate2 cert = sel[0]; Org.BouncyCastle.X509.X509CertificateParser cp = new Org.BouncyCastle.X509.X509CertificateParser(); Org.BouncyCastle.X509.X509Certificate[] chain = new Org.BouncyCastle.X509.X509Certificate[] { cp.ReadCertificate(cert.RawData)}; IExternalSignature externalSignature = new X509Certificate2Signature(cert,"SHA-1"); PdfReader pdfReader = new PdfReader(pathToBasePdf); signedPdf = new FileStream(pathToBasePdf,FileMode.Create); pdfStamper = PdfStamper.CreateSignature(pdfReader,signedPdf,'\0'); PdfSignatureAppearance signatureAppearance = pdfStamper.SignatureAppearance; signatureAppearance.SignatureGraphic = Image.GetInstance(pathToSignatureImage); signatureAppearance.SetVisibleSignature(new Rectangle(100,100,250,150),pdfReader.NumberOfPages,"Signature"); signatureAppearance.SignatureRenderingMode = PdfSignatureAppearance.RenderingMode.GRAPHIC_AND_DESCRIPTION; MakeSignature.SignDetached(signatureAppearance,externalSignature,CryptoStandard.CMS);