pyOpenSSL:验证证书链:适用于 2 但不适用于更多
pyOpenSSL : verify certificates chain : works with 2 but not with more
我构建了自己的证书链并尝试对其进行验证。
当我只有 2 个证书(根 CA 和待验证的证书)时:它工作正常。
当我有 3 个(根 CA、中间和待验证的 CA)时:我收到消息“invalid CA certificate”。
这是一个极简代码:
import OpenSSL
def create_cert_chain ( nb ):
chain = []
issuer_key = None
issuer_name = None
is_root = True
for i in range( nb ):
my_name = b'certificate #%d'%i # certificate #0 is the root CA
cert = OpenSSL.crypto.X509()
my_key = OpenSSL.crypto.PKey()
my_key . generate_key( OpenSSL.crypto.TYPE_RSA,2048 )
if is_root :
cert.add_extensions( [OpenSSL.crypto.X509Extension(b"subjectKeyIdentifier", False, b"hash",subject=cert)])
cert.add_extensions( [OpenSSL.crypto.X509Extension(b"authorityKeyIdentifier", False, b"keyid:always",issuer=cert)])
cert.add_extensions( [OpenSSL.crypto.X509Extension(b"basicConstraints", False, b"CA:TRUE,pathlen:5")])
cert.add_extensions( [OpenSSL.crypto.X509Extension(b"keyUsage", False, b"keyCertSign, cRLSign")])
cert.get_subject().O = my_name
cert.get_issuer().O = my_name if is_root else issuer_name
cert.gmtime_adj_notBefore( 0 )
cert.gmtime_adj_notAfter( 365*24*60*60 )
cert.set_pubkey( my_key )
cert.sign( my_key if is_root else issuer_key,'sha256' )
chain += [cert]
issuer_key = my_key
issuer_name = my_name
is_root = False
return chain
def check_chain ( nb ):
chain = create_cert_chain( nb )
store = OpenSSL.crypto.X509Store()
for cert in chain[:-1] :
print( 'store certificate%s'%cert.get_subject().O )
store.add_cert( cert )
print( 'check certificate%s'%chain[-1].get_subject().O )
ctx = OpenSSL.crypto.X509StoreContext( store,chain[-1] )
ctx.verify_certificate()
print('ok')
check_chain( 2 ) # works fine
check_chain( 3 ) # fails with "invalid CA certificate"
我做错了什么?
我怀疑扩展有误,但我不知道它是什么...
顺便问一下,为什么它只适用于 2 个证书?
我发现了我的错误:基本约束 CA:TRUE
不仅适用于根证书,还适用于所有中间证书。
所以,正确的测试是if i < nb-1 :
(而不是if is_root :
)。
添加如果我想尽可能限制路径长度,我必须将其设置为 nb-i-2
.
顺便说一句,根据我的需要,所有其他扩展都是可选的。
我构建了自己的证书链并尝试对其进行验证。
当我只有 2 个证书(根 CA 和待验证的证书)时:它工作正常。
当我有 3 个(根 CA、中间和待验证的 CA)时:我收到消息“invalid CA certificate”。
这是一个极简代码:
import OpenSSL
def create_cert_chain ( nb ):
chain = []
issuer_key = None
issuer_name = None
is_root = True
for i in range( nb ):
my_name = b'certificate #%d'%i # certificate #0 is the root CA
cert = OpenSSL.crypto.X509()
my_key = OpenSSL.crypto.PKey()
my_key . generate_key( OpenSSL.crypto.TYPE_RSA,2048 )
if is_root :
cert.add_extensions( [OpenSSL.crypto.X509Extension(b"subjectKeyIdentifier", False, b"hash",subject=cert)])
cert.add_extensions( [OpenSSL.crypto.X509Extension(b"authorityKeyIdentifier", False, b"keyid:always",issuer=cert)])
cert.add_extensions( [OpenSSL.crypto.X509Extension(b"basicConstraints", False, b"CA:TRUE,pathlen:5")])
cert.add_extensions( [OpenSSL.crypto.X509Extension(b"keyUsage", False, b"keyCertSign, cRLSign")])
cert.get_subject().O = my_name
cert.get_issuer().O = my_name if is_root else issuer_name
cert.gmtime_adj_notBefore( 0 )
cert.gmtime_adj_notAfter( 365*24*60*60 )
cert.set_pubkey( my_key )
cert.sign( my_key if is_root else issuer_key,'sha256' )
chain += [cert]
issuer_key = my_key
issuer_name = my_name
is_root = False
return chain
def check_chain ( nb ):
chain = create_cert_chain( nb )
store = OpenSSL.crypto.X509Store()
for cert in chain[:-1] :
print( 'store certificate%s'%cert.get_subject().O )
store.add_cert( cert )
print( 'check certificate%s'%chain[-1].get_subject().O )
ctx = OpenSSL.crypto.X509StoreContext( store,chain[-1] )
ctx.verify_certificate()
print('ok')
check_chain( 2 ) # works fine
check_chain( 3 ) # fails with "invalid CA certificate"
我做错了什么?
我怀疑扩展有误,但我不知道它是什么...
顺便问一下,为什么它只适用于 2 个证书?
我发现了我的错误:基本约束 CA:TRUE
不仅适用于根证书,还适用于所有中间证书。
所以,正确的测试是if i < nb-1 :
(而不是if is_root :
)。
添加如果我想尽可能限制路径长度,我必须将其设置为 nb-i-2
.
顺便说一句,根据我的需要,所有其他扩展都是可选的。