禁用 AuthenticateAsServer 的证书验证似乎不起作用
Disable certificate validation for AuthenticateAsServer doesn't seem to work
我正在开发一个更大的 C# 套接字应用程序,它将通过 SSL 使用服务器和客户端身份验证。为了在我的本地机器上测试应用程序的其他部分,我需要禁用证书验证。我已经尝试按照其他几个地方的建议覆盖 ServerCertificateValidatioNCallback,但我仍然遇到异常。我正在使用使用 OpenSSL 创建的自签名证书进行测试。
我尝试过的解决方案文章:
- Disabling certificate revocation checking for an application on Windows
- How to ignore the certificate check when ssl
- C# Ignore certificate errors?
我遇到的异常:
StackTrace: at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, Exception exception)
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.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.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.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.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.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.Security.SslStream.AuthenticateAsServer(X509Certificate serverCertificate, Boolean clientCertificateRequired, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation)
我已将我的服务器代码缩减为以下内容:
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
X509Certificate2 cert = new X509Certificate2("server.pfx", "password");
IPAddress ip = IPAddress.Parse("127.0.0.1");
TcpListener server = new TcpListener(ip, 8000);
server.Start();
TcpClient client = server.AcceptTcpClient();
Console.WriteLine(client.Client.RemoteEndPoint.ToString() + ":" + ((IPEndPoint)client.Client.RemoteEndPoint).Port + " connected");
SslStream ssl = new SslStream(client.GetStream(), false);
ssl.AuthenticateAsServer(cert, true, SslProtocols.Tls, false);
而客户端代码如下:
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
TcpClient client = new TcpClient("127.0.0.1", 8000);
X509Certificate2Collection coll = new X509Certificate2Collection();
coll.Add(new X509Certificate2("client.pfx", "password"));
byte[] data = Encoding.UTF8.GetBytes("Hello from the client!");
using (SslStream ssl = new SslStream(client.GetStream(), false))
{
ssl.AuthenticateAsClient("127.0.0.1", coll, SslProtocols.Tls, false);
ssl.Write(data, 0, data.Length);
data = new Byte[8192];
int bytes = 0;
string resp = "";
do
{
bytes = ssl.Read(data, 0, data.Length);
if (bytes > 0) resp += System.Text.Encoding.ASCII.GetString(data, 0, bytes);
}
while (bytes > 0);
Console.WriteLine("Response: " + resp);
}
client.Close();
AuthenticateAsServer 和AuthenticateAsClient 出现异常。应用程序的设计需要使用客户端证书。
我试过将 PFX 文件导入证书存储区,结果没有任何区别。
我还尝试使用 makecert 重新创建自签名证书和私钥,并使用 pvk2pfx.exe 转换为 PFX,结果没有任何区别。我的想法是,它们可能是在另一台机器上创建的问题。
显然这一行还不够:
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
我不得不将我的 SslStream 从:
(服务器)
SslStream ssl = new SslStream(client.GetStream(), false);
和(客户)
using (SslStream ssl = new SslStream(client.GetStream(), false))
收件人:
(服务器)
SslStream ssl = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateCert));
和(客户)
using (SslStream ssl = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateCert)))
并添加以下方法:
public static bool ValidateCert(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true; // Allow untrusted certificates.
}
显然这优先于:ServicePointManager.ServerCertificateValidationCallback
代表。
显然,我现在需要弄清楚如何修改 ValidateCert 以有选择地允许不受信任的证书。
我正在开发一个更大的 C# 套接字应用程序,它将通过 SSL 使用服务器和客户端身份验证。为了在我的本地机器上测试应用程序的其他部分,我需要禁用证书验证。我已经尝试按照其他几个地方的建议覆盖 ServerCertificateValidatioNCallback,但我仍然遇到异常。我正在使用使用 OpenSSL 创建的自签名证书进行测试。
我尝试过的解决方案文章:
- Disabling certificate revocation checking for an application on Windows
- How to ignore the certificate check when ssl
- C# Ignore certificate errors?
我遇到的异常:
StackTrace: at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, Exception exception)
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.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.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.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.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.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.Security.SslStream.AuthenticateAsServer(X509Certificate serverCertificate, Boolean clientCertificateRequired, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation)
我已将我的服务器代码缩减为以下内容:
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
X509Certificate2 cert = new X509Certificate2("server.pfx", "password");
IPAddress ip = IPAddress.Parse("127.0.0.1");
TcpListener server = new TcpListener(ip, 8000);
server.Start();
TcpClient client = server.AcceptTcpClient();
Console.WriteLine(client.Client.RemoteEndPoint.ToString() + ":" + ((IPEndPoint)client.Client.RemoteEndPoint).Port + " connected");
SslStream ssl = new SslStream(client.GetStream(), false);
ssl.AuthenticateAsServer(cert, true, SslProtocols.Tls, false);
而客户端代码如下:
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
TcpClient client = new TcpClient("127.0.0.1", 8000);
X509Certificate2Collection coll = new X509Certificate2Collection();
coll.Add(new X509Certificate2("client.pfx", "password"));
byte[] data = Encoding.UTF8.GetBytes("Hello from the client!");
using (SslStream ssl = new SslStream(client.GetStream(), false))
{
ssl.AuthenticateAsClient("127.0.0.1", coll, SslProtocols.Tls, false);
ssl.Write(data, 0, data.Length);
data = new Byte[8192];
int bytes = 0;
string resp = "";
do
{
bytes = ssl.Read(data, 0, data.Length);
if (bytes > 0) resp += System.Text.Encoding.ASCII.GetString(data, 0, bytes);
}
while (bytes > 0);
Console.WriteLine("Response: " + resp);
}
client.Close();
AuthenticateAsServer 和AuthenticateAsClient 出现异常。应用程序的设计需要使用客户端证书。
我试过将 PFX 文件导入证书存储区,结果没有任何区别。
我还尝试使用 makecert 重新创建自签名证书和私钥,并使用 pvk2pfx.exe 转换为 PFX,结果没有任何区别。我的想法是,它们可能是在另一台机器上创建的问题。
显然这一行还不够:
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
我不得不将我的 SslStream 从: (服务器)
SslStream ssl = new SslStream(client.GetStream(), false);
和(客户)
using (SslStream ssl = new SslStream(client.GetStream(), false))
收件人: (服务器)
SslStream ssl = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateCert));
和(客户)
using (SslStream ssl = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateCert)))
并添加以下方法:
public static bool ValidateCert(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true; // Allow untrusted certificates.
}
显然这优先于:ServicePointManager.ServerCertificateValidationCallback
代表。
显然,我现在需要弄清楚如何修改 ValidateCert 以有选择地允许不受信任的证书。