AuthenticateAsClient失败并显示CRYPT_E_ASN1_BADTAG

问题描述 投票:0回答:1

我编写了一个.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;
}

例外:

例外:在System.Net.Security的System.Net.Security.SslStreamPal.AcquireCredentialsHandle(CredentialUse credUsage,SCHANNEL_CRED secureCredential)的System.Net.SSPIWrapper.AcquireCredentialsHandle(SSPIInterface secModule,String package,CredentialUse intent,SCHANNEL_CRED scc)中的ASN1UngültigerKennzeichenwert。 SslStreamPal.AcquireCredentialsHandle(X509证书证书,SslProtocols协议,EncryptionPolicy策略,Boolean isServer),位于System.Net.Security.SecureChannel.GenerateToken(Byte []输入,Int32的System.Net.Security.SecureChannel.AcquireClientCredentials(Byte []&thumbPrint) System.Net.Security.SslState.StartSendBlob(Byte []传入,Int32处的System.Net.Security.SecureChannel.NextMessage(字节[]传入,Int32偏移量,Int32计数)处的偏移量,Int32计数,字节[]和输出) System.Net.Security.SslState.StartRe在System.Net.Security.SslState.ProcessReceivedBlob(Byte []缓冲区,Int32计数,AsyncProtocolRequest asyncRequest)处计数,AsyncProtocolRequest asyncRequest) System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message,AsyncProtocolRequest asyncRequest)上的System.Net.Security.SslState.StartReceiveBlob(Byte []缓冲区,AsyncProtocolRequest asyncRequest)中的adFrame(Byte []缓冲区,Int32 readBytes,AsyncProtocolRequest asyncRequest)在System.Net.Security的System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst,Byte [] buffer,AsyncProtocolRequest asyncRequest)中的System.Net.Security.SslState.StartSendBlob(Byte [] incoming,Int32 count,AsyncProtocolRequest asyncRequest)。 System.Net.Security.SslStream.AuthenticateAsClient上的SslState.ProcessAuthentication(LazyAsyncResult lazyResult)(String targetHost,X509CertificateCollection clientCertificates,SslProtocols enabledSslProtocols,Boolean checkCertificateRevocation)

像往常一样,MS失败的原因还不够详细,无法解决问题。有没有办法找出证书中大约70个标签中的哪一个无效?

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

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

UPDATE

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

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;
}
c# .net bouncycastle x509certificate2 ecdsa
1个回答
0
投票

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.