vb.net - 使用 BouncyCaSTLe 的 key 对于在指定状态 CryptographicException 中使用无效

标签 vb.net security exception cryptography itextsharp

一直在搜索网络和博客并到处寻找碎片,并尝试将它们放在一起以便能够使用 System.Security.Cryptography.X509Certificates 通过 iTextSharp 对 PDF 文件进行数字签名图书馆。

我有一个签名按钮,后面有以下代码:

    Dim m As New PdfManipulation
    Dim store As New X509Store("MY", StoreLocation.CurrentUser)
    store.Open(OpenFlags.ReadOnly Or OpenFlags.OpenExistingOnly)

    Dim collection As X509Certificate2Collection = CType(store.Certificates, X509Certificate2Collection)
    Dim fcollection As X509Certificate2Collection = CType(collection.Find(X509FindType.FindByTimeValid, DateTime.Now, False), X509Certificate2Collection)
    Dim scollection As X509Certificate2Collection = X509Certificate2UI.SelectFromCollection(fcollection, "Test Certificate Select", "Select a certificate from the following list to get information on that certificate", X509SelectionFlag.SingleSelection)

    For Each x509 As X509Certificate2 In scollection
        m.DigitallySignPdf("C:\Users\my\Desktop\populates.pdf", "C:\Users\my\Desktop\A.pdf", "topmostSubform[0].Page1[0].SignatureField1[0]", x509)
    Next x509

    store.Close()

上面的代码有效,它打开了我的证书库,我选择了一个证书。然后它将证书传递给以下 PdfManiuplation 类进行签名。

Pdf操作代码:

Public Class PdfManipulation

Public Sub DigitallySignPdf(ByVal sourceDocument As String, _
                            ByVal destinationPath As String, _
                            ByVal fieldNameToSign As String, _
                            ByVal signature As X509Certificate2)

    Dim reader As New PdfReader(sourceDocument)
    Using fout As New FileStream(destinationPath, FileMode.Create, FileAccess.ReadWrite)
        Using stamper As PdfStamper = PdfStamper.CreateSignature(reader, fout, ControlChars.NullChar)
            ' appearance
            Dim appearance As PdfSignatureAppearance = stamper.SignatureAppearance
            appearance.SetVisibleSignature(fieldNameToSign)

            ' digital signature
            Dim akp = Org.BouncyCastle.Security.DotNetUtilities.GetKeyPair(signature.PrivateKey).Private
            Dim es As IExternalSignature = New PrivateKeySignature(akp, "SHA-256")
            Dim cp As New Org.BouncyCastle.X509.X509CertificateParser()


            MakeSignature.SignDetached(appearance, es, New Org.BouncyCastle.X509.X509Certificate() {cp.ReadCertificate(signature.RawData)}, Nothing, Nothing, Nothing, 0, CryptoStandard.CMS)

            stamper.Close()

        End Using
    End Using

End Sub

End Class

当它到达

Dim akp = Org.BouncyCastle.Security.DotNetUtilities.GetKeyPair(signature.PrivateKey).Private

那是抛出异常的时候。我选择的证书与我在我的机器上签署所有内容的证书相同,所以我知道它很好。对于为什么会抛出此错误的任何帮助,或指向正确方向的指针,我们将不胜感激。

这也是我的进口 list :

Imports System.Security.Cryptography
Imports System.Security.Permissions
Imports System.IO
Imports System.Security.Cryptography.X509Certificates
Imports iTextSharp.text.pdf.security
Imports iTextSharp.text
Imports iTextSharp.text.pdf

并且必须添加对以下内容的引用:

System.Security

堆栈跟踪:

    System.Security.Cryptography.CryptographicException was unhandled
  HResult=-2146893813
  Message=Key not valid for use in specified state.

  Source=mscorlib
  StackTrace:
       at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)
       at System.Security.Cryptography.Utils._ExportKey(SafeKeyHandle hKey, Int32 blobType, Object cspObject)
       at System.Security.Cryptography.RSACryptoServiceProvider.ExportParameters(Boolean includePrivateParameters)
       at Org.BouncyCastle.Security.DotNetUtilities.GetRsaKeyPair(RSA rsa)
       at Org.BouncyCastle.Security.DotNetUtilities.GetKeyPair(AsymmetricAlgorithm privateKey)
       at AccessRequest.PdfManipulation.DigitallySignPdf(String sourceDocument, String destinationPath, String fieldNameToSign, X509Certificate2 signature) in C:\PdfManipulation.vb:line 237
       at Form.btnSubmit_Click(Object sender, EventArgs e) in C:\Form.vb:line 251
       at System.Windows.Forms.Control.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ButtonBase.WndProc(Message& m)
       at System.Windows.Forms.Button.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(ApplicationContext context)
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
       at app.My.MyApplication.Main(String[] Args) in 11111.vb:line 81
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 

此外,在进一步测试并通过 IDE 查看私钥之后,我确实注意到了

signature.privatekey.CspKeyContainerInfo.Exportable = False

这是否可能是错误的原因?如果是,如何使选定的证书可导出?正如我通过搜索看到的唯一一件事实际上是创建一个新证书并将 StorageFlag 设置为 Exportable 而我并没有尝试创建一个新证书。我只是想使用选定的证书。

最佳答案

错误是由于私有(private)证书不可导出造成的。

我一直在想,在我所有的测试中,为什么我一次都没有被提示输入我选择的证书的智能卡密码。这导致我最终选择了一个我知道不会要求 pin 和 viola 的证书,导出并签署了 pdf。甚至通过代码查看证书私钥属性,这次它读取

signature.privatekey.CspKeyContainerInfo.Exportable = True

这最终与我发现的另一种形式相匹配,表示他们通过使私钥可导出来修复错误。现在我所要做的就是弄清楚如何使用应该要求我提供 pin 的证书来完成这项工作。如果我发现这个问题,我会发回这里。

关于vb.net - 使用 BouncyCaSTLe 的 key 对于在指定状态 CryptographicException 中使用无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20685807/

相关文章:

jquery - 如何以多列表格格式显示自动完成列表?

php - https 安全 cookie 是否可以防止 XSS 攻击?

java - JAVA 中的 PKCS5 或基于密码的加密 (PBE)

python - 抓取 PyQt 中的任何异常

java - Tomcat 8 无法加载网站

mysql - 如何比较 VB ListView 中的数据和 MySQL 数据库中的数据?

vb.net - Systems.timer.timer不需要的多线程

vb.net - 如何在没有 IDispatch 的情况下创建 VB.NET COM 可见接口(interface)?

security - 如何在 tomcat 6 中将 session cookie 标记为安全(仅限 https)

java - Java 中使用 ArrayList 的异常处理