繁体   English   中英

在PyOpenSSL中验证客户端证书

[英]Validating client certificates in PyOpenSSL

我正在编写一个需要在客户端浏览器中安装证书的应用程序。 我在PyOpenSSL文档中找到了这个“Context”对象,但是我看不出回调应该如何验证证书,只是它应该以某种方式。

set_verify(mode, callback)
      Set the verification flags for this Context object to mode and
      specify that callback should be used for verification callbacks.
      mode should be one of VERIFY_NONE and VERIFY_PEER. If
      VERIFY_PEER is used, mode can be OR:ed with
      VERIFY_FAIL_IF_NO_PEER_CERT and VERIFY_CLIENT_ONCE to further
      control the behaviour. callback should take five arguments: A
      Connection object, an X509 object, and three integer variables,
      which are in turn potential error number, error depth and return
      code. callback should return true if verification passes and
      false otherwise.

我告诉Context对象我的(自签名)密钥在哪里(见下文),所以我想我不明白为什么这个库不足以检查客户端提供的证书是否有效。 在这个回调函数中应该怎么做?

class SecureAJAXServer(PlainAJAXServer):
    def __init__(self, server_address, HandlerClass):
        BaseServer.__init__(self, server_address, HandlerClass)
        ctx = SSL.Context(SSL.SSLv23_METHOD)
        ctx.use_privatekey_file ('keys/server.key')
        ctx.use_certificate_file('keys/server.crt')
        ctx.set_session_id("My_experimental_AJAX_Server")
        ctx.set_verify( SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT | SSL.VERIFY_CLIENT_ONCE, callback_func )
        self.socket = SSL.Connection(ctx, socket.socket(self.address_family, self.socket_type))
        self.server_bind()
        self.server_activate()

警告:在这里编写乐趣,不是专业人士,所以如果我的Q揭示了我的完全跛足,天真和/或基本缺乏理解,那么在SSL方面请不要太粗暴!

谢谢 :)

罗杰

set_verify()OpenSSL文档中,您关心的键是返回码

回调应该采用五个参数:一个Connection对象,一个X509对象和三个整数变量,这些变量又是潜在的错误号,错误深度和返回码 如果验证通过,回调应返回true,否则返回false。

有一个完整的工作示例,或多或少地显示了您想要做的事情: 何时验证客户端证书?

基本上你可以忽略前4个参数,只需检查第五个参数中的返回码的值,如下所示:

from OpenSSL.SSL import Context, Connection, SSLv23_METHOD
from OpenSSL.SSL import VERIFY_PEER, VERIFY_FAIL_IF_NO_PEER_CERT, VERIFY_CLIENT_ONCE

class SecureAJAXServer(BaseServer):
    def verify_callback(connection, x509, errnum, errdepth, ok):
        if not ok:
            print "Bad Certs"
        else:
            print "Certs are fine"
        return ok

    def __init__(self, server_address, HandlerClass):
        BaseServer.__init__(self, server_address, HandlerClass)
        ctx = Context(SSLv23_METHOD)
        ctx.use_privatekey_file ('keys/server.key')
        ctx.use_certificate_file('keys/server.crt')
        ctx.set_session_id("My_experimental_AJAX_Server")
        ctx.set_verify( VERIFY_PEER | VERIFY_FAIL_IF_NO_PEER_CERT | VERIFY_CLIENT_ONCE, verify_callback )
        self.socket = Connection(ctx, socket.socket(self.address_family, self.socket_type))
        self.server_bind()
        self.server_activate()

注意:我做了另外一个from OpenSSL.SSL import ...更改from OpenSSL.SSL import ...在我测试时稍微简化了你的代码,所以你没有SSL. 每个导入符号前面的前缀。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM