18

我一直在努力解决一个问题,也许你们可以指出我正确的方向。

我正在尝试通过 https 连接在网络服务器上对 pdf 进行数字签名。

在页面加载时,我这样做:

HttpClientCertificate cs = Request.ClientCertificate;
X509Certificate card = new X509Certificate(cs.Certificate);
Org.BouncyCastle.X509.X509CertificateParser cp = new Org.BouncyCastle.X509.X509CertificateParser();
 Org.BouncyCastle.X509.X509Certificate[] chain = new Org.BouncyCastle.X509.X509Certificate[] { cp.ReadCertificate(card.GetRawCertData())};

我在最后一行代码中收到错误“m_safeCertContext 是无效句柄”。

请注意:

  • 我使用 2 个完全不同的证书时遇到了同样的错误。
  • 证书正在检索到“卡”变量 ok。
  • 我曾经将卡转换为 X509Certificate2,但我昨天在某处读到,我无法通过转换为 X509Certificate 然后向下转换为 X509Certificate2 来解决该错误。这是那些“嗯……这没有任何意义,但我还没有尝试过”的时刻之一。
  • 我试图向[System.Security.SecurityCritical, System.Security.SecurityTreatAsSafe]所有方法甚至类添加属性,以查看它是否可以工作......没有这样的运气。

谁能给我一个提示?

4

3 回答 3

16

每当您访问密码学中未初始化的字段时,都可能发生这种情况。

在您的代码中,如果返回一个没有原始证书数据的对象,那么您将在第四行Request.ClientCertificate调用时看到错误。card.GetRawCertData()

作为一个简单的测试,请尝试以下操作:

var cert = new System.Security.Cryptography.X509Certificates.X509Certificate2();
Console.WriteLine(cert.Thumbprint);

这将引发以下异常,因为没有可用的指纹:

m_safeCertContext is an invalid handle.

使用给定的堆栈跟踪:

at System.Security.Cryptography.X509Certificates.X509Certificate.ThrowIfContextInvalid()
at System.Security.Cryptography.X509Certificates.X509Certificate.SetThumbprint()
at System.Security.Cryptography.X509Certificates.X509Certificate.GetCertHashString()
at System.Security.Cryptography.X509Certificates.X509Certificate2.get_Thumbprint()
at MyEncryptionUtility.EncryptionUtilityForm.button1_Click(Object sender, EventArgs e) in C:\MyEncryptionUtility\EncryptionUtilityForm.cs:line 2864
于 2013-11-21T19:45:39.547 回答
2

看起来这不是您的问题,但对其他人而言:确保在尝试访问任何与证书相关的属性或方法之前不要调用 X509Certificate2.Reset() 。

于 2016-12-12T14:58:11.040 回答
0
 public bool ReadCertFromSignedFile(X509Certificate2 cert, string filename)
    {
        if (!string.IsNullOrWhiteSpace(filename) && File.Exists(filename))
        {
            var cert509 = X509Certificate.CreateFromSignedFile(filename);
            cert = new X509Certificate2(cert509.GetRawCertData());

            return CheckSertificate(cert);
        }
        else
        { throw new Exception("Сертификат не заполнен"); }
    }

从这样的另一个代码调用方法

   if (_digitalSignatureService.ReadCertFromSignedFile(fileCert, file.SignFilePath))
                 {
                    if (!cert.Equals(fileCert))
                    {

等于 - 调用错误“m_safeCertContext 是无效句柄”。因为 X509Certificate 不存在

决定

 public bool ReadCertFromSignedFile(X509Certificate2 cert, string filename)
    {
        if (!string.IsNullOrWhiteSpace(filename) && File.Exists(filename))
        {
            var cert509 = X509Certificate.CreateFromSignedFile(filename);

            cert.Import(cert509.GetRawCertData());

此代码有效!

于 2016-12-16T15:22:19.000 回答