用Python、Ruby或Perl连接.NET Sslstream x.509套接字

2 投票
1 回答
2062 浏览
提问于 2025-04-16 07:31

我有一个比较奇怪的需求。我想和一个用C#写的服务器进行通信。大概是这样的:

 SslStream sslStream = new SslStream(client.GetStream(), true,
                                   ValidateServerCertificate,
                                   SelectLocalCertificate); 
sslStream.AuthenticateAsServer(_pushCert);

我还有一段C#的示例代码,它使用了一个X509证书并连接到服务器。我也有这个cert.pfx文件的密码。

我想做的是设置一个脚本,可以连接到这个socket,发送一些字节并接收响应。(其实用什么语言都可以,不过我在考虑Python、Ruby或者Perl)

我试着用Python的SSL封装,但出现了一个错误,提示没有已知的算法可以让服务器和客户端进行通信。

这是我用Python写的代码示例:

ss = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s = ssl.wrap_socket(ss, ca_certs=CERT, ssl_version=ssl.PROTOCOL_SSLv23 )
#Attempt connection to our server
try:
    s.connect((HOST, PORT))
    print s
except:
    print 'ERROR Connecting'
    sys.exit(0)

关于证书,我试过几种不同的文件:.pfx文件,还有一些用openssl从.pfx提取出来的文件。

我也尝试了很多不同的示例(ssl.wrap_socket的参数)。不过我对这些连接的知识也不是很熟悉。

也许这里有人可以帮帮我?

谢谢!

1 个回答

0

你可以简化一下SslStream构造函数的调用:

SslStream sslStream = new SslStream(client.GetStream()); 
sslStream.AuthenticateAsServer(_pushCert);

这个服务器会发送一个叫做_pushCert的东西,并且不指望客户端会返回证书。服务器需要这个证书的私钥来建立SSL连接。

客户端只需要一个CA根证书,这个证书是用来签署服务器证书的(或者可以选择接受一个不被信任的证书)。这个根证书需要放在“受信任的根证书存储”里,或者以其他方式被客户端认为是可信的。

如果服务器的证书是由一个中间CA证书签署的,而这个中间CA证书又是由根CA证书签署的,那么客户端也需要这个中间证书。这个中间证书可以由服务器发送,或者客户端已经有了。不管怎样,客户端必须拥有整个签署证书链,以便验证链上的所有签名。中间CA证书不需要放在受信任的根存储里。

双方都不需要CA根证书或中间签署证书的私钥。

不过,如果你的服务器希望客户端发送一个客户端证书,那么你需要在调用AuthenticateAsServer时提供更多的参数(clientCertificateRequired == true)。在这种情况下,客户端需要自己的证书和这个证书的私钥。服务器需要在其受信任的存储中有签署客户端证书的CA根证书。客户端包装器可以接受一个pfx文件,比如,里面包含客户端证书和私钥。服务器不需要客户端的私钥。

撰写回答