PowerShell SSL套接字客户端

3
我使用PowerShell连接到一个带有自签名证书的SSL套接字时遇到了问题。我有一个Ruby客户端可以正常连接,并且我还使用了ncat和--ssl开关进行了测试,确认它也可以正常连接。$sslStream.AuthenticateAsClient是代码失败的地方,我从PowerShell中获得以下错误:"Exception calling "AuthenticateAsClient" with "1" argument(s): "A call to SSPI failed, see inner exception."。非常感谢任何帮助。 PowerShell客户端
$socket = New-Object Net.Sockets.TcpClient('172.26.4.38', 8080)
$stream = $socket.GetStream()
$sslStream = New-Object System.Net.Security.SslStream($stream,$false,({$True} -as [Net.Security.RemoteCertificateValidationCallback]))
$sslStream.AuthenticateAsClient('172.26.4.38')
$writer = new-object System.IO.StreamWriter($sslStream)
$writer.WriteLine('hello world')
$writer.flush()
$socket.close()

Ruby服务器

#!/usr/bin/env ruby
require 'openssl'
require 'socket'
tcp_server = TCPServer.new('172.26.4.38', 8080)
ctx = OpenSSL::SSL::SSLContext.new
ctx.ssl_version = :SSLv23
ctx.key = OpenSSL::PKey::RSA.new 2048
ctx.cert = OpenSSL::X509::Certificate.new
ctx.cert.subject = OpenSSL::X509::Name.new [['CN', '172.26.4.38']]
ctx.cert.issuer = ctx.cert.subject
ctx.cert.public_key = ctx.key
ctx.cert.not_before = Time.now
ctx.cert.not_after = Time.now + 60 * 60 * 24
ctx.cert.sign ctx.key, OpenSSL::Digest::SHA1.new
server = OpenSSL::SSL::SSLServer.new tcp_server, ctx
socket = server.accept
puts 'client connected'
puts socket.gets

只是想指出,如果您每次连接都重新生成自签名证书,那么客户端将无法将其作为受信任的锚点,因此您总是必须通过忽略无效证书的方式来绕过此问题,这也会使您的连接易受中间人攻击。 - Bruno
2个回答

2
这是一个关于 Ruby 代码创建自签名证书的问题。使用 OpenSSL 和 openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout server.key -out server.crt,以下 PowerShell 代码可以正常工作。 客户端
$socket = New-Object Net.Sockets.TcpClient('172.26.4.38', 8080)
$stream = $socket.GetStream()
$sslStream = New-Object System.Net.Security.SslStream($stream,$false,({$True} -as [Net.Security.RemoteCertificateValidationCallback]))
$sslStream.AuthenticateAsClient('172.26.4.38')
$writer = new-object System. IO.StreamWriter($sslStream)
$writer.WriteLine('Hello World')
$writer.flush()
$socket.close()

服务器
#!/usr/bin/env ruby
require 'openssl'
require 'socket'
tcp_server = TCPServer.new('172.26.4.38', 8080)
ctx = OpenSSL::SSL::SSLContext.new
ctx.cert = OpenSSL::X509::Certificate.new(File.open('server.crt'))
ctx.key = OpenSSL::PKey::RSA.new(File.open('server.key'))
server = OpenSSL::SSL::SSLServer.new tcp_server, ctx 
socket = server.accept
puts 'client connected'
puts socket.gets

根据服务器上的TLS设置,您可能需要在AuthenticateAsClient之前使用[System.Net.ServicePointManager]::SecurityProtocol = 'Tls11,Tls12,Tls13' - undefined

0

你可以通过强制回调函数始终返回 true 来让 PowerShell 忽略任何证书问题。

[Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}

请注意,这将绕过 PowerShell 会话中的任何 SSL 验证。


我已经尝试过这个方法,也尝试了以下代码:$sslStream = New-Object System.Net.Security.SslStream($socket.GetStream(),$false,({$True} -as [Net.Security.RemoteCertificateValidationCallback]))但出于某种原因,它仍然无法正常工作。它在证书处一直失败。 - b00stfr3ak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接