2010-12-09 214 views
13

我需要驗證證書是否由我的自定義CA簽署。使用OpenSSL命令行工具,這是很容易做到:如何在python中驗證SSL證書?

# Custom CA file: ca-cert.pem 
# Cert signed by above CA: bob.cert 
$ openssl verify -CAfile test-ca-cert.pem bob.cert 
bob.cert: OK 

但我需要做同樣的事情在Python,我真的不想調出命令行實用程序。據我所知,M2Crypto是OpenSSL的「最完整的」python包裝,但我無法弄清楚如何完成命令行工具的功能!

參考this question對於如何在C代碼中完成相同的任務,我已經能夠獲得大約一半的時間。 我選擇的變量名稱與openssl verify命令行實用程序的源代碼中使用的名稱相同,請參閱openssl-xxx/apps/verify.c

import M2Crypto as m2 
# Load the certificates 
cacert = m2.X509.load_cert('test-ca-cert.pem') # Create cert object from CA cert file 
bobcert = m2.X509.load_cert('bob.cert')  # Create cert object from Bob's cert file 
cert_ctx = m2.X509.X509_Store()    # Step 1 from referenced C code steps 
csc = m2.X509.X509_Store_Context(cert_ctx) # Step 2 & 5 
cert_ctx.add_cert(cacert)     # Step 3 
cert_ctx.add_cert(bobcert)     # ditto 
# Skip step 4 (no CRLs to add) 
# Step 5 is combined with step 2...I think. (X509_STORE_CTX_init: Python creates and 
# initialises an object in the same step) 
# Skip step 6? (can't find anything corresponding to 
# X509_STORE_CTX_set_purpose, not sure if we need to anyway???) 
# 
# It all falls apart at this point, as steps 7 and 8 don't have any corresponding 
# functions in M2Crypto -- I even grepped the entire source code of M2Crypto, and 
# neither of the following functions are present in it: 
# Step 7: X509_STORE_CTX_set_cert - Tell the context which certificate to validate. 
# Step 8: X509_verify_cert - Finally, validate it 

所以我中途有,但我似乎無法真正得到確認完成!我錯過了什麼嗎?是否還有其他的功能,我應該從M2Crypto使用?我應該尋找一個完全不同的OpenSSL python包裝嗎?我如何在python中完成這個任務!?!?

請注意,我使用證書來加密/解密文件,所以我對使用基於SSL連接的對等證書驗證(其中有already been answered)沒有興趣,因爲我沒有任何SSL連接去。

+1

是否有任何理由你不想調用命令行工具?似乎你可以爲自己節省一大筆頭痛...... – katrielalex 2010-12-09 21:08:12

+2

是的,這是針對將被部署在許多不同的操作系統上的軟件,無論新老,大小,都包括潛在的嵌入式系統(足夠大以包含python) )。我想要最大的便攜性和最高性能。如果我可以避免的話,我不想讓潛在的成千上萬個呼叫進入命令行。涉及大量證書。 – Nathan 2010-12-09 22:20:35

+0

相關http://stackoverflow.com/q/2626792/4279 – jfs 2010-12-16 05:34:23

回答

-3

就像你說的, OpenSSL的需要連接

M2Crypto不具有良好的驗證

這樣如何巧妙的構思:

import os 
os.system('openssl verify -CAfile ../ca-cert.pem bob.cert') 

它醜陋,但它的工程!

-1

您可以使用遺憾的未公開的X509.verify方法來檢查證書是否使用CA的私鑰簽名。作爲這一調用OpenSSL的x509_verify的背景下,我敢肯定,這也是正確的檢查所有參數(如過期):

from M2Crypto X509 

cert = X509.load_cert("certificate-filename") 

caCertificate = X509.load_cert("trusted-ca-filename") 
caPublic = caCertificate.get_pubkey() 

if cert.verify(caPublic) == 1: 
    # Certificate is okay! 
else: 
    # not okay 
5

你不能用普通M2Crypto做到這一點,因爲它不換一些必要的功能。好消息是,如果你安裝了SWIG,你可以自己打包並使用M2Crypto代碼。我前段時間爲自己製作了一些額外功能的模塊,並決定現在發佈它,因爲它進行了這種驗證。你可以在這裏查看:https://github.com/abbot/m2ext。這是一個例子,如何使用此模塊驗證證書:

import sys 
from m2ext import SSL 
from M2Crypto import X509 

print "Validating certificate %s using CApath %s" % (sys.argv[1], sys.argv[2]) 
cert = X509.load_cert(sys.argv[1]) 
ctx = SSL.Context() 
ctx.load_verify_locations(capath=sys.argv[2]) 
if ctx.validate_certificate(cert): 
    print "valid" 
else: 
    print "invalid" 

不幸的是M2Crypto發展似乎是停滯(在bug跟蹤系統沒有閉合問題在過去的兩年中)和維護者無視我的錯誤和電子郵件與這些和其他一些補丁...