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 控制台是我需要解决这个问题的提示。
我编写了一个 .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 控制台是我需要解决这个问题的提示。