使用Ruby中的SSLServer验证客户端证书

时间:2022-11-19 19:40:10

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?

但是,服务器在尝试获取无法找到的peer_cert时会抛出异常。有没有办法让SSLServer期望客户端证书?

1 个解决方案

#1


7  

Have a look at test_client_auth and start_server in the tests for OpenSSL::SSL.

在OpenSSL :: SSL的测试中查看test_client_auth和start_server。

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

从我的头脑中,我在代码中看到的唯一遗漏是你忘了在服务器端明确要求客户端身份验证 - 设置标志组合很重要

flags = OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
ctx.verify_mode = flags

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.

这样服务器实际上将需要客户端身份验证,而不是静默接受未经身份验证的请求。如果您没有设置这些,服务器将很高兴,而不会请求客户端身份验证,因此也没有可用的对等证书。

#1


7  

Have a look at test_client_auth and start_server in the tests for OpenSSL::SSL.

在OpenSSL :: SSL的测试中查看test_client_auth和start_server。

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

从我的头脑中,我在代码中看到的唯一遗漏是你忘了在服务器端明确要求客户端身份验证 - 设置标志组合很重要

flags = OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
ctx.verify_mode = flags

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.

这样服务器实际上将需要客户端身份验证,而不是静默接受未经身份验证的请求。如果您没有设置这些,服务器将很高兴,而不会请求客户端身份验证,因此也没有可用的对等证书。