我正在编写一个需要在客户端浏览器中安装证书的应用程序。我在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显示我的完全跛足,天真和/或基本缺乏理解,那么请不要太粗暴!
谢谢:)
罗杰
答案 0 :(得分:6)
在set_verify()
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()
中,您关注的关键是返回代码:
回调应该采用五个参数:一个Connection对象,一个X509 对象和三个整数变量,这些变量又是潜在的错误 数字,错误深度和返回代码。回调应该返回true 如果验证通过,否则为假。
有一个完整的工作示例,或多或少地显示了您想要做的事情:OpenSSL documentation
基本上你可以忽略前4个参数,只需检查第五个参数中返回码的值,如下所示:
from OpenSSL.SSL import ...
注意:我进行了另一项更改SSL.
,以便在我测试时简化您的代码,这样您就不会在每个导入符号前面加上{{1}}前缀。