我正在尝试在.NET和Java之间创建一个SSL套接字服务器/客户端。在这种情况下,我的SSL套接字服务器将在.net中运行,而客户端将在Linux下的Java中运行。我的问题是在握手过程中连接失败,特别是当服务器从客户端请求证书时,客户端无法向后发送东西并且连接失败。

在.net中,我使用sslStream建立连接,而在Java上,我使用标准SSLSocket。下面是一些代码片段,但这是我到目前为止的内容:

在服务器端(Windows),我在MMC下的“个人/证书”文件夹中有一个私有(private)证书。我在受信任的人/证书中有来自客户端的公共(public)证书。两种证书都是由同一CA颁发的。这两个证书的证书链具有多个级别,但是两者都相同。链中的根级别证书也安装在受信任的证书颁发机构/证书文件夹中。

在客户端(Linux)上,我有一个 keystore ,其中包含与服务器上安装的公共(public)证书匹配的私有(private)证书。我有一个信任库,其中包含来自服务器的公共(public)证书,与服务器的私有(private)证书匹配。

在服务器端(.net)上,我使用一个执行异步读取的套接字,然后将其包装到SSLStream中,代码片段如下所示:

NetworkStream ns = new NetworkStream(socket, false);
SslStream ssl = new SslStream(ns, true);
ssl.AuthenticateAsServer(serverCertificate, true, SslProtocols.Default, true);

客户端代码几乎是标准代码:
SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
InetAddress addr = InetAddress.getByName(servername);
SSLSocket socket = (SSLSocket) factory.createSocket(addr,port);
socket.setUseClientMode(true);
socket.setNeedClientAuth(true);
socket.setWantClientAuth(true);
socket.startHandshake();
os = new DataOutputStream(socket.getOutputStream());
is = new DataInputStream(socket.getInputStream());
byte[] outBuf = new byte[50];
os.write("SEND SOMETHING".getBytes("UTF-8"));
is.read(outBuf);

在Java中,我设置了适当的varialbes以使用其密码指向信任和 key 存储。

现在,遵循标准的SSL握手,将发生以下情况:
  • 客户端您好
  • 服务器您好
  • 服务器发送公共(public)证书
  • 客户端将公共(public)证书与信任库
  • 中的证书进行匹配
  • 服务器发送证书请求
  • 使用证书请求,服务器将发送有效CA的列表,在此列表上仅发送我的根CA(在其他知名CA的长长列表中)。
  • 客户端证书为空。
  • 服务器从客户端接收到空证书,因此关闭了连接。

  • 就是这样,客户端不会将有效证书发送回服务器。我对此有一些疑问:

    有没有人经历过这样的事情?
    关于服务器(Windows)发送的CA列表,.net如何确定要发送给客户端的内容?有没有办法修改该列表?
    我是否需要在该CA列表中发送用于在我的证书上签名的链中的所有权限?还是根足够?

    我在代码的两边都缺少什么吗?

    任何帮助将不胜感激。

    最佳答案

    以下两个语句在客户端无用(尽管它们不应该受到伤害):

    socket.setNeedClientAuth(true);
    socket.setWantClientAuth(true);
    

    您看到“证书请求”消息和“客户端证书”消息的事实表明服务器配置正确。

    客户端证书消息中缺少证书的最可能的原因是, keystore (在客户端)可能未正确配置。您可能对this answer感兴趣,以确保正确配置了客户端 keystore 。更具体地说,您需要确保以与证书链相同的别名导入客户端证书的私钥(并且该链回到证书请求消息中广告的CA)。

    (关于您问题的其余部分,我不确定在C#中使用SslStream时如何修改服务器发送的CA列表。This earlier question似乎表明没有解决方案,尽管较新版本的.Net可能已解决了该问题。自从问了这个问题以来,我无法通过查看SslStream API文档和相关类找到任何可以解决此问题的方法,但这并不意味着它不存在。

    09-30 18:55
    查看更多