c# - SSL 连接在没有客户端身份验证的情况下失败
问题描述
我读到客户端身份验证是可选的,所以我试图连接到我的 SSL 服务器而不在客户端进行身份验证。当我这样做时,我在服务器上收到以下错误:
, in accept_connection
ssl_version=ssl.PROTOCOL_SSLv23
File "/usr/lib/python2.7/ssl.py", line 933, in wrap_socket
ciphers=ciphers)
File "/usr/lib/python2.7/ssl.py", line 601, in __init__
self.do_handshake()
File "/usr/lib/python2.7/ssl.py", line 830, in do_handshake
self._sslobj.do_handshake()
SSLEOFError: EOF occurred in violation of protocol (_ssl.c:590)
这是工作服务器和客户端代码,当我在客户端进行身份验证时一切正常,但是当我注释掉该行时会出现错误。
服务器(蟒蛇):
def accept_connection(self, sock):
client, (addr, port) = sock.accept()
sslclient = ssl.wrap_socket(
client,
server_side=True,
certfile=self.ssl_cert_file,
keyfile=self.ssl_key_file,
ssl_version=ssl.PROTOCOL_SSLv23
)
客户端(C#):
public bool Connect()
{
try
{
client = new TcpClient(this.ServerAddress, this.ServerPort);
sslStream = new SslStream(
client.GetStream(),
false,
new RemoteCertificateValidationCallback(ValidateCert),
null
);
try
{
sslStream.AuthenticateAsClient(this.ServerAddress);
}
catch (AuthenticationException e)
{
sslStream = null;
client.Close();
client = null;
return false;
}
}
catch (Exception e)
{
return false;
}
return true;
}
以上是没有错误的工作代码。
当我在客户端上注释掉以下代码时:
//sslStream.AuthenticateAsClient(this.ServerAddress);
上面提到的python错误出现了,客户端连接没有抛出任何异常并继续运行直到第一次读取,然后失败:
This operation is only allowed using a successfully authenticated context.
如果我不打电话,我该如何进行这项工作AuthenticateAsClient
?
这就是我生成证书文件和密钥文件的方式
openssl req -x509 -newkey rsa:1024 -keyout my.key -out my.crt -days 365 -nodes -subj "/C=US/ST=VA/L=Junk/O=None/OU=Junk/CN=example.local"
Python 是第 2 版。
也许我刚刚被误导,调用AuthenticateAsClient
是可选的?
解决方案
SSL客户端证书身份验证确实是可选的。当客户端将其证书发送到服务器时,服务器会验证此证书是否有效,是服务器所期望的,并使用该证书对客户端进行身份验证。
然而,这不是由
sslStream.AuthenticateAsClient(this.ServerAddress);
如文档所述,此方法是
由客户端调用以对服务器进行身份验证,并且可以选择在客户端-服务器连接中对客户端进行身份验证。
验证服务器(验证其证书有效,为预期域颁发,由受信任的机构颁发)是 ssl 握手中的必需步骤。例如,使用此链接的描述,我们看到第 3 步是:
SSL 或 TLS 客户端验证服务器的数字证书
服务器等待来自客户端的此步骤的结果以继续。出于这个原因,如果您通过注释调用来跳过此步骤AuthenticateAsClient
- 您的 python 服务器正确地抱怨协议违规。
要使用客户端身份验证,您将使用另一个重载:
X509CertificateCollection clientCerts = GetClientCerts();
sslStream.AuthenticateAsClient(this.ServerAddress, clientCerts, true);
由于您没有这样做 - 您没有执行(可选)客户端身份验证。
推荐阅读
- node.js - node.js 堆内存和使用的堆大小 [pm2]
- oauth - JWT:使用 grant_type=password 时刷新令牌的优势是什么
- jsf - JSF 条件样式在运行时不起作用
- reactjs - Graphql 查询中的参数无效
- kubernetes - 是否可以将磁盘安装到 gke pod 和计算引擎
- flutter - Flutter项目中pubspec.lock文件有什么用
- elixir - handle_event 不适用于 Phoenix LiveView 示例
- javascript - 如何在 React 中动态更改文本的颜色?
- python - Web Scraping - 从多个页面中提取文本列表
- php - CodeIgniter 4 在视图布局上从数据库填充菜单