【问题标题】:AuthenticatAsClient fails with CRYPT_E_ASN1_BADTAGAuthenticatAsClient 失败并显示 CRYPT_E_ASN1_BADTAG
【发布时间】:2018-02-28 07:51:58
【问题描述】:

我编写了一个 .NET 应用程序,它尝试使用 ECC 客户端证书进行相互身份验证(曲线是 BrainpoolP384r1)。 该证书由 PKI 签名,当我在 ASN1 查看器中查看它时,它似乎完全有效。 我通过以下方式获取证书字节数据:

Console.WriteLine($"Certificate:{BitConverter.ToString(cert.RawData).Replace("-","")}");

在 MMC 控制台中查看证书似乎也是有效的。

但是,当我尝试使用它作为客户端进行身份验证时,它会以CRYPT_E_ASN1_BADTAG 失败。

我尝试验证的代码-sn-p:

TcpClient client = new TcpClient(serverName, 9909);
Console.WriteLine("Client connected.");
SslStream sslStream = new SslStream(
    client.GetStream(),
    false,
    new RemoteCertificateValidationCallback(ValidateServerCertificate),
    null
);

try
{
    var certificates = new X509CertificateCollection();
    certificates.Add(cert);
    sslStream.AuthenticateAsClient(serverName, certificates, SslProtocols.Tls12, false);
}
catch (Exception e)
{
    Console.WriteLine("Exception: {0} \n{1}", e.Message, e.StackTrace);
    if (e.InnerException != null)
    {
        Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
    }

    Console.WriteLine("Authentication failed - closing the connection.");
    client.Close();
    return;
}

例外:

例外:ASN1 Ungültiger Kennzeichenwert 在 System.Net.SSPIWrapper.AcquireCredentialsHandle(SSPI 接口 secModule、字符串包、CredentialUse 意图、SCHANNEL_CRED scc) 在 System.Net.Security.SslStreamPal.AcquireCredentialsHandle(CredentialUse credUsage,SCHANNEL_CRED 安全凭证) 在 System.Net.Security.SslStreamPal.AcquireCredentialsHandle(X509Certificate 证书、SslProtocols 协议、EncryptionPolicy 策略、布尔值 是服务器) 在 System.Net.Security.SecureChannel.AcquireClientCredentials(字节 []& 拇指印) 在 System.Net.Security.SecureChannel.GenerateToken(Byte[] 输入,Int32 偏移量,Int32 计数,Byte[]& 输出) 在 System.Net.Security.SecureChannel.NextMessage(字节 [] 传入,Int32 偏移量,Int32 计数) 在 System.Net.Security.SslState.StartSendBlob(字节 [] 传入,Int32 计数,AsyncProtocolRequest asyncRequest) 在 System.Net.Security.SslState.ProcessReceivedBlob(字节 [] 缓冲区,Int32 计数,AsyncProtocolRequest asyncRequest) 在 System.Net.Security.SslState.StartReadFrame(字节 [] 缓冲区,Int32 读取字节,AsyncProtocolRequest asyncRequest) 在 System.Net.Security.SslState.StartReceiveBlob(字节 [] 缓冲区,AsyncProtocolRequest asyncRequest) 在 System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken 消息,AsyncProtocolRequest asyncRequest) 在 System.Net.Security.SslState.StartSendBlob(字节 [] 传入,Int32 计数,AsyncProtocolRequest asyncRequest) 在 System.Net.Security.SslState.ForceAuthentication(布尔接收第一,字节 [] 缓冲区,AsyncProtocolRequest asyncRequest) 在 System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult 懒惰的结果) 在 System.Net.Security.SslStream.AuthenticateAsClient(字符串 targetHost,X509CertificateCollection clientCertificates,SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation)

与 MS 一样,失败的原因不够详细,无法解决问题。有什么办法可以查出证书中大约 70 个标签中的哪一个是无效的?

还有一条信息:密钥对和 csr 是使用 bouncycastle 创建的,因为我没有找到仅使用 .NET 进行 cmp 请求的方法。这可能是原因吗?但是为什么证书在 mmc 控制台中显示为有效呢?

很抱歉没有提供完整的可验证示例,但即使是用于创建 csr、发送它、将私钥附加到证书并将其存储在 MYStore 中的精简代码也太长了,而且没有 PKI 绝对没用。

更新

从商店加载证书的代码如下:

static X509Certificate2 LoadFromStore(string commonName)
{
    var distinguishedName = "CN=" + commonName;
    var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
    store.Open(OpenFlags.ReadOnly);

    X509Certificate2 result = null;

    foreach (var cert in store.Certificates)
    {
        if (cert.SubjectName.Name != null && cert.SubjectName.Name.Equals(distinguishedName))
        {
           Console.WriteLine("Found certificate in local store: " + cert.SubjectName.Name);

            result = cert;
            break;
        }
    }

    store.Close();
    return result;
}

【问题讨论】:

  • 如何获得证书?
  • @pepo 更新了我的问题以包含我如何从商店加载证书的信息。
  • 你确定证书已经找到了吗?当你运行X509Certificate2.Verify 时会发生什么?您正在打开 CurrentUser 商店。您确定证书在正确的用户存储(您的存储)中吗?
  • @pepo 这很有趣。 cert.Verify() 返回 false,但如果我按照问题开头所述将证书字节写入控制台并将输出粘贴到 ASN1 查看器,一切看起来都不错。
  • 好的,在命令行中尝试certutil -user -store my。 Certutil 将检查 CurrentUser\My 商店中的所有证书及其私钥。它给你的证书带来什么结果?加密/签名通过?

标签: c# .net bouncycastle x509certificate2 ecdsa


【解决方案1】:

像往常一样,在使用 microsoft API 时,错误与真正的原因无关...... :-(

所有这一切的原因是错误的 csr 使接收到的证书具有有效的 ASN1 结构(使用http://lapo.it/asn1js/ 验证)和无效的内容。如何正确操作可以在this SO question的答案中找到。

用户 pepo 帮助我走上了正轨(再次感谢您!)。 他建议使用 certutil -user -store my 而不是查看 MMC 控制台的评论是我需要解决这个问题的提示。

【讨论】:

    猜你喜欢
    • 2015-12-31
    • 1970-01-01
    • 2021-12-10
    • 2020-02-08
    • 2011-05-21
    • 2012-05-04
    • 2019-07-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多