簡體   English   中英

Python 3 - 從X509證書中提取公鑰並使用它進行加密

[英]Python 3 - Extract public key from X509 certificate and encrypt with it

由於M2Crypto庫不適用於Python 3,我正在尋找一種讀取X509證書的方法,從中提取公鑰並將其用於RSA加密。

我目前有以下兩個功能:

from ssl import PEM_cert_to_DER_cert  # standard library
from Crypto.Util import asn1  # http://pycrypto.org
from OpenSSL.crypto import *  # https://pythonhosted.org/pyOpenSSL/

def extract_publickey_1(certstr):
    """ from http://stackoverflow.com/questions/12911373 """
    der = PEM_cert_to_DER_cert(certstr)
    cert = asn1.DerSequence()
    cert.decode(der)
    tbs = asn1.DerSequence()
    tbs.decode(cert[0])
    return tbs[6]

def extract_publickey_2(certstr):
    return dump_privatekey(FILETYPE_ASN1, 
                           load_certificate(FILETYPE_PEM, certstr).get_pubkey())

第一個函數為某些證書引發了一​​個IndexError ,特別是那些不是從命令行OpenSSL生成的證書,而是一些加密庫(python和c#libs已經過測試)。它適用於命令行OpenSSL生成的證書。

我檢查了第二個函數的輸出,它與第一個函數的輸出不同,但輸出的最后266個字節是等價的:

extract_publickey_1(certstr)[-266:] == extract_publickey_2(certstr)[-266:]

返回True

我的問題是,這里發生了什么? 這個問題有方法解決嗎?

首先,您必須明白,因為X.509證書是以ASN.1格式編碼的,所以它被表示為各種值的深層和任意嵌套集合 - 並且嵌套樣式和值數據類型可能是任意的在DER模式下。 因此,期望固定位置和固定形式的字段是非常天真的,即沒有進一步的嵌套和嚴格的數據類型(特別是當涉及到文本字符串時); 更不用說使用“魔術常數” 總是一個壞主意。 這就是為什么你應該盡可能使用get_pubkey()這樣的專用函數, 而不是像在asn1類中那樣自己解析復雜的文檔

其次,您必須了解,因為X.509規范與算法無關,所以沒有“RSA模數”,“RSA公共指數”等特定字段。 相反,只有一個通用的“公鑰”字段,它有一組嵌套的子字段 - 指定算法OID及其數字屬性。 例如,RSA公鑰有2個屬性:模數n和加密指數e ; 另外,你的extract_publickey_2()函數會預先設置一個始終為零的屬性,我不知道它代表什么。 您的RSA實現需要數字參數而不是字節數組或復雜的ASN.1值的機會很高,這就是您可能需要使用asn1.DerSequence.decode()或更多RSA特定函數來提取它們的原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM