簡體   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