用Python、Ruby或Perl连接.NET Sslstream x.509套接字
我有一个比较奇怪的需求。我想和一个用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 个回答
你可以简化一下SslStream构造函数的调用:
SslStream sslStream = new SslStream(client.GetStream());
sslStream.AuthenticateAsServer(_pushCert);
这个服务器会发送一个叫做_pushCert的东西,并且不指望客户端会返回证书。服务器需要这个证书的私钥来建立SSL连接。
客户端只需要一个CA根证书,这个证书是用来签署服务器证书的(或者可以选择接受一个不被信任的证书)。这个根证书需要放在“受信任的根证书存储”里,或者以其他方式被客户端认为是可信的。
如果服务器的证书是由一个中间CA证书签署的,而这个中间CA证书又是由根CA证书签署的,那么客户端也需要这个中间证书。这个中间证书可以由服务器发送,或者客户端已经有了。不管怎样,客户端必须拥有整个签署证书链,以便验证链上的所有签名。中间CA证书不需要放在受信任的根存储里。
双方都不需要CA根证书或中间签署证书的私钥。
不过,如果你的服务器希望客户端发送一个客户端证书,那么你需要在调用AuthenticateAsServer时提供更多的参数(clientCertificateRequired == true)。在这种情况下,客户端需要自己的证书和这个证书的私钥。服务器需要在其受信任的存储中有签署客户端证书的CA根证书。客户端包装器可以接受一个pfx文件,比如,里面包含客户端证书和私钥。服务器不需要客户端的私钥。