使用M2Crypto保存和加载PEM格式的X509证书
我本以为,如果我把一个X509证书作为对象保存在内存中,然后把它保存为pem文件,再把它加载回来,我应该能得到和最开始一样的证书。但事实似乎并非如此。我们把原来的证书叫做A,从pem文件加载的证书叫做B。A.as_text()和B.as_text()是完全一样的,但A.as_pem()和B.as_pem()却不一样。说实话,我对此感到很困惑。顺便提一下,如果A是由另一个实体C签名的,那么A会通过C的证书进行验证,但B却不能。
我写了一个小程序来演示我看到的情况。当我运行这个程序时,会出现第二个RuntimeError错误。
谢谢,
Brock
#!/usr/bin/python2.6
import M2Crypto as m2
import time
cur_time = m2.ASN1.ASN1_UTCTIME()
cur_time.set_time(int(time.time()) - 60*60*24)
expire_time = m2.ASN1.ASN1_UTCTIME()
# Expire certs in 1 hour.
expire_time.set_time(int(time.time()) + 60 * 60 * 24)
cs_rsa = m2.RSA.gen_key(1024, 65537, lambda: None)
cs_pk = m2.EVP.PKey()
cs_pk.assign_rsa(cs_rsa)
cs_cert = m2.X509.X509()
# These two seem the minimum necessary to make the as_text function call work
# at all
cs_cert.set_not_before(cur_time)
cs_cert.set_not_after(expire_time)
# This seems necessary to fill out the complete cert without errors.
cs_cert.set_pubkey(cs_pk)
# I've tried with the following set lines commented out and not commented.
cs_name = m2.X509.X509_Name()
cs_name.C = "US"
cs_name.ST = "CA"
cs_name.OU = "Fake Org CA 1"
cs_name.CN = "www.fakeorg.dex"
cs_name.Email = "cs1@www.fakeorg.dex"
cs_cert.set_subject(cs_name)
cs_cert.set_issuer_name(cs_name)
cs_cert.sign(cs_pk, md="sha256")
orig_text = cs_cert.as_text()
orig_pem = cs_cert.as_pem()
print "orig_text:\n%s" % orig_text
cs_cert.save_pem("/tmp/foo")
tcs = m2.X509.load_cert("/tmp/foo")
tcs_text = tcs.as_text()
tcs_pem = tcs.as_pem()
if orig_text != tcs_text:
raise RuntimeError(
"Texts were different.\nOrig:\n%s\nAfter load:\n%s" %
(orig_text, tcs_text))
if orig_pem != tcs_pem:
raise RuntimeError(
"Pems were different.\nOrig:\n%s\nAfter load:\n%s" %
(orig_pem, tcs_pem))
1 个回答
1
如果你用OpenSSL命令行工具创建了一个证书(比如说在测试目录里的server.pem,没有包含密钥和文本),然后用M2Crypto加载并保存这个证书,你应该会得到完全一样的文件。
我原以为在contrib目录里的SimpleX509Create.py的工作方式不一样,但我测试后发现,和你遇到的问题一样,结果也是一样的。显然,我们漏掉了OpenSSL命令行工具中某个步骤。