在 Ruby 中使用 SSLServer 验证客户端证书
这是我用来设置服务器的代码:
require 'socket'
require 'openssl'
socket = TCPServer.new('127.0.0.1', 4433)
ssl_context = OpenSSL::SSL::SSLContext.new()
ssl_context.cert = OpenSSL::X509::Certificate.new(File.open("ssl/server/server.crt"))
ssl_context.key = OpenSSL::PKey::RSA.new(File.open("ssl/server/server.key"))
ca_cert = OpenSSL::X509::Certificate.new(File.open("ssl/ca/ca.crt"))
ssl_socket = OpenSSL::SSL::SSLServer.new(socket, ssl_context)
Thread.start(ssl_socket.accept) do |s|
puts "Connected to #{s.peeraddr.last}"
if s.peer_cert.verify(ca_cert.public_key)
puts "Certificate verified"
else
puts "Certificate invalid"
end
end
和客户端:
require 'socket'
require 'openssl'
socket = TCPSocket.new('127.0.0.1', 4433)
ssl_context = OpenSSL::SSL::SSLContext.new
ssl_context.cert = OpenSSL::X509::Certificate.new(File.open("ssl/client1/client1.crt"))
ssl_context.key = OpenSSL::PKey::RSA.new(File.open("ssl/client1/client1.key"))
ssl_socket = OpenSSL::SSL::SSLSocket.new(socket, ssl_context)
ca_cert = OpenSSL::X509::Certificate.new(File.open("ssl/ca/ca.crt"))
ssl_socket.connect
if ssl_socket.peer_cert.verify(ca_cert.public_key)
puts "Certificate checks out"
else
puts "Certificate not verified"
end
但是,当服务器尝试获取它找不到的peer_cert 时,它会抛出异常。有没有办法让 SSLServer 期待客户端证书?
Heres the code I'm using to setup the server:
require 'socket'
require 'openssl'
socket = TCPServer.new('127.0.0.1', 4433)
ssl_context = OpenSSL::SSL::SSLContext.new()
ssl_context.cert = OpenSSL::X509::Certificate.new(File.open("ssl/server/server.crt"))
ssl_context.key = OpenSSL::PKey::RSA.new(File.open("ssl/server/server.key"))
ca_cert = OpenSSL::X509::Certificate.new(File.open("ssl/ca/ca.crt"))
ssl_socket = OpenSSL::SSL::SSLServer.new(socket, ssl_context)
Thread.start(ssl_socket.accept) do |s|
puts "Connected to #{s.peeraddr.last}"
if s.peer_cert.verify(ca_cert.public_key)
puts "Certificate verified"
else
puts "Certificate invalid"
end
end
And the client:
require 'socket'
require 'openssl'
socket = TCPSocket.new('127.0.0.1', 4433)
ssl_context = OpenSSL::SSL::SSLContext.new
ssl_context.cert = OpenSSL::X509::Certificate.new(File.open("ssl/client1/client1.crt"))
ssl_context.key = OpenSSL::PKey::RSA.new(File.open("ssl/client1/client1.key"))
ssl_socket = OpenSSL::SSL::SSLSocket.new(socket, ssl_context)
ca_cert = OpenSSL::X509::Certificate.new(File.open("ssl/ca/ca.crt"))
ssl_socket.connect
if ssl_socket.peer_cert.verify(ca_cert.public_key)
puts "Certificate checks out"
else
puts "Certificate not verified"
end
However, the server throws an exception when it tries to get the peer_cert that it cannot find. Is there a way to get the SSLServer to expect a client certificate?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
看看 test_client_auth 和 start_server 在
OpenSSL::SSL
测试中。从我的角度来看,我在您的代码中看到的唯一缺失是您忘记在服务器端明确要求客户端身份验证 - 设置标志组合非常重要,
以便服务器实际上要求 客户端身份验证,而不是默默地接受未经身份验证的请求。如果您不设置这些,服务器将很乐意不请求客户端身份验证,因此也将没有可用的对等证书。
Have a look at test_client_auth and start_server in the tests for
OpenSSL::SSL
.From the top of my head, the only thing I see missing in your code is that you forgot to explicitly require client authentication on the server side - it is important to set the flag combination
so that the server will actually require client authentication and not silently accept requests that come unauthenticated. If you don't set these, the server will be happy without requesting client authentication and as a result there will also be no peer certificate available.