X.509 證書結構描述
常見的X.509證書格式包括:
后綴 | 作用 |
---|---|
cer/crt | 用於存放證書,它是2進制形式存放的,不含私鑰 |
pem | 以Ascii來表示,可以用於存放證書或私鑰。 |
pfx/p12 | 用於存放個人證書/私鑰,他通常包含保護密碼,2進制方式。 |
p10 | 證書請求 |
p7r | CA對證書請求的回復,只用於導入 |
p7b | 以樹狀展示證書鏈(certificate chain),同時也支持單個證書,不含私鑰。 |
對於常見的https證書 一般是用crt或者pem來保存, http證書可電器網頁前的鎖按鈕得到, 並且進行導出
證書數據結構
此證書結構來着白皮書
https://tools.ietf.org/html/rfc2459#section-4.1
Certificate ::= SEQUENCE {
tbsCertificate TBSCertificate, -- 證書主體
signatureAlgorithm AlgorithmIdentifier, -- 證書簽名算法標識
signatureValue BIT STRING --證書簽名值,是使用signatureAlgorithm部分指定的簽名算法對tbsCertificate證書主題部分簽名后的值.
}
TBSCertificate ::= SEQUENCE {
version [0] EXPLICIT Version DEFAULT v1, -- 證書版本號
serialNumber CertificateSerialNumber, -- 證書序列號,對同一CA所頒發的證書,序列號唯一標識證書
signature AlgorithmIdentifier, --證書簽名算法標識
issuer Name, --證書發行者名稱
validity Validity, --證書有效期
subject Name, --證書主體名稱
subjectPublicKeyInfo SubjectPublicKeyInfo,--證書公鑰
issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
-- 證書發行者ID(可選),只在證書版本2、3中才有
subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
-- 證書主體ID(可選),只在證書版本2、3中才有
extensions [3] EXPLICIT Extensions OPTIONAL
-- 證書擴展段(可選),只在證書版本3中才有
}
Version ::= INTEGER { v1(0), v2(1), v3(2) }
CertificateSerialNumber ::= INTEGER
AlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER,
parameters ANY DEFINED BY algorithm OPTIONAL }
parameters:
Dss-Parms ::= SEQUENCE { -- parameters ,DSA(DSS)算法時的parameters,
RSA算法沒有此參數
p INTEGER,
q INTEGER,
g INTEGER }
signatureValue:
Dss-Sig-Value ::= SEQUENCE { -- sha1DSA簽名算法時,簽名值
r INTEGER,
s INTEGER }
Name ::= CHOICE {
RDNSequence }
RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
RelativeDistinguishedName ::=
SET OF AttributeTypeAndValue
AttributeTypeAndValue ::= SEQUENCE {
type AttributeType,
value AttributeValue }
AttributeType ::= OBJECT IDENTIFIER
AttributeValue ::= ANY DEFINED BY AttributeType
Validity ::= SEQUENCE {
notBefore Time, -- 證書有效期起始時間
notAfter Time -- 證書有效期終止時間
}
Time ::= CHOICE {
utcTime UTCTime,
generalTime GeneralizedTime }
UniqueIdentifier ::= BIT STRING
SubjectPublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier, -- 公鑰算法
subjectPublicKey BIT STRING -- 公鑰值
}
subjectPublicKey:
RSAPublicKey ::= SEQUENCE { -- RSA算法時的公鑰值
modulus INTEGER, -- n
publicExponent INTEGER -- e -- }
Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
Extension ::= SEQUENCE {
extnID OBJECT IDENTIFIER,
critical BOOLEAN DEFAULT FALSE,
extnValue OCTET STRING }
參考博客:
https://blog.csdn.net/xy010902100449/article/details/52145009
源代碼
這里利用的是python3 的 Openssl 庫進行解析, 此庫的說明文檔如下,
https://pyopenssl.org/en/0.15.1/api/crypto.html#x509name-objects
通過閱讀說明文檔, 可以輕松讀取證書相關信息
代碼如下
import OpenSSL
import time
from dateutil import parser
cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, open("test.cer").read())
certIssue = cert.get_issuer()
print ("證書版本: ",cert.get_version() + 1)
print ("證書序列號: ",hex(cert.get_serial_number()))
print ("證書中使用的簽名算法: ",cert.get_signature_algorithm().decode("UTF-8"))
print ("頒發者: ",certIssue.commonName)
datetime_struct = parser.parse(cert.get_notBefore().decode("UTF-8"))
print ("有效期從: ",datetime_struct.strftime('%Y-%m-%d %H:%M:%S'))
datetime_struct = parser.parse(cert.get_notAfter().decode("UTF-8"))
print ("到: ",datetime_struct.strftime('%Y-%m-%d %H:%M:%S'))
print ("證書是否已經過期: ",cert.has_expired())
print("公鑰長度" ,cert.get_pubkey().bits())
print("公鑰:\n" ,OpenSSL.crypto.dump_publickey(OpenSSL.crypto.FILETYPE_PEM, cert.get_pubkey()).decode("utf-8"))
print("主體信息:")
print("CN : 通用名稱 OU : 機構單元名稱")
print("O : 機構名 L : 地理位置")
print("S : 州/省名 C : 國名")
for item in certIssue.get_components():
print(item[0].decode("utf-8"), " —— ",item[1].decode("utf-8"))
print(cert.get_extension_count())
編譯運行輸出結果
windows 自帶的解析結果對比
是完全相同的. 讀取成功