AuthenticatAsClient 失败 CRYPT_E_ASN1_BADTAG

AuthenticatAsClient fails with CRYPT_E_ASN1_BADTAG

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

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

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

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

我尝试验证的代码片段:

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;
}

异常:

Exception: ASN1 Ungültiger Kennzeichenwert at System.Net.SSPIWrapper.AcquireCredentialsHandle(SSPIInterface secModule, String package, CredentialUse intent, SCHANNEL_CRED scc) at System.Net.Security.SslStreamPal.AcquireCredentialsHandle(CredentialUse credUsage, SCHANNEL_CRED secureCredential) at System.Net.Security.SslStreamPal.AcquireCredentialsHandle(X509Certificate certificate, SslProtocols protocols, EncryptionPolicy policy, Boolean isServer) at System.Net.Security.SecureChannel.AcquireClientCredentials(Byte[]& thumbPrint) at System.Net.Security.SecureChannel.GenerateToken(Byte[] input, Int32 offset, Int32 count, Byte[]& output) at System.Net.Security.SecureChannel.NextMessage(Byte[] incoming, Int32 offset, Int32 count) at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult) at System.Net.Security.SslStream.AuthenticateAsClient(String 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;
}

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

所有这一切的原因是错误的 csr 使收到的证书具有有效的 ASN1 结构(已通过 http://lapo.it/asn1js/) with invalid content. How to do it right can be found in the answer to 验证。

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