如何使用Python输出仅限证书的PKCS#7
我正在用Python实现一个服务器。SCEP规范要求我对如何使用Python输出仅限证书的PKCS#7,python,ruby,openssl,Python,Ruby,Openssl,我正在用Python实现一个服务器。SCEP规范要求我对PKI操作做出“仅证书PKCS#7”的响应。Apple在Ruby中有一个参考实现,它实现了以下功能 require 'openssl' @@root_cert = OpenSSL::X509::Certificate.new(File.read("ca_cert.pem")) @@ra_cert = OpenSSL::X509::Certificate.new(File.read("ra_cert.pem")) scep_certs =
PKI操作
做出“仅证书PKCS#7”的响应。Apple在Ruby中有一个参考实现,它实现了以下功能
require 'openssl'
@@root_cert = OpenSSL::X509::Certificate.new(File.read("ca_cert.pem"))
@@ra_cert = OpenSSL::X509::Certificate.new(File.read("ra_cert.pem"))
scep_certs = OpenSSL::PKCS7.new()
scep_certs.type="signed"
scep_certs.certificates=[@@root_cert, @@ra_cert]
File.open('from_ruby.der', 'w') { |file| file.write(scep_certs.to_der)}
from M2Crypto import X509
ca_cert = X509.load_cert('ca_cert.pem')
ra_cert = X509.load_cert('ra_cert.pem')
stack = X509.X509_Stack()
stack.push(ca_cert)
stack.push(ra_cert)
derFile = open('from_python.der', 'w')
derFile.write(stack.as_der())
该代码正确输出包含CA和RA证书的PCKS7 DER文件。我正在尝试将此代码移植到Python。我正在使用M2Crypto库访问OpenSSL。我正在与没有证书
方法这一事实作斗争。到目前为止,我已经得出以下结论
require 'openssl'
@@root_cert = OpenSSL::X509::Certificate.new(File.read("ca_cert.pem"))
@@ra_cert = OpenSSL::X509::Certificate.new(File.read("ra_cert.pem"))
scep_certs = OpenSSL::PKCS7.new()
scep_certs.type="signed"
scep_certs.certificates=[@@root_cert, @@ra_cert]
File.open('from_ruby.der', 'w') { |file| file.write(scep_certs.to_der)}
from M2Crypto import X509
ca_cert = X509.load_cert('ca_cert.pem')
ra_cert = X509.load_cert('ra_cert.pem')
stack = X509.X509_Stack()
stack.push(ca_cert)
stack.push(ra_cert)
derFile = open('from_python.der', 'w')
derFile.write(stack.as_der())
这段Python代码确实输出了一个DER编码的文件,它看起来确实包含两个证书。但是,OpenSSL无法读取此文件
openssl pkcs7 -in from_ruby.der -inform DER -print_certs
打印Ruby脚本中的证书就可以了,而
openssl pkcs7 -in from_python.der -inform DER -print_certs
抛出此错误
unable to load PKCS7 object
89377:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:/SourceCache/OpenSSL098/OpenSSL098-47.1/src/crypto/asn1/tasn_dec.c:1315:
89377:error:0D06C03A:asn1 encoding routines:ASN1_D2I_EX_PRIMITIVE:nested asn1 error:/SourceCache/OpenSSL098/OpenSSL098-47.1/src/crypto/asn1/tasn_dec.c:827:
89377:error:0D08303A:asn1 encoding routines:ASN1_TEMPLATE_NOEXP_D2I:nested asn1 error:/SourceCache/OpenSSL098/OpenSSL098-47.1/src/crypto/asn1/tasn_dec.c:747:Field=type, Type=PKCS7
如何让Python以与Ruby相同的格式输出CA和RA证书
更新:
我找到了生成相同文件的openssl命令
openssl crl2pkcs7 -nocrl -certfile ca_cert.pem -certfile ra_cert.pem -out crl.der -outform DER
现在,我如何在Python中实现这一点。这与相同,我有一种感觉(完全未经测试)是这样的:
an_smime = M2Crypto.SMIME.SMIME()
an_smime.set_x509_stack(stack)
an_smime.write(M2Crypto.BIO.File('from_python.der'), pkcs7=True)
具有相同的要求,并最终分叉M2Crypto以添加一个新函数,该函数将创建一个退化的PKCS7对象 涉及的步骤如下:
\u pkcs7.i
SWIG接口文件以添加以下功能//添加与X.509相关的头文件,以便能够使用其数据类型。
#包括
#包括
//添加PKCS7_签名数据类型以帮助创建退化数据结构。
%应用指针非空{PKCS7_SIGNED*};
//用于退化PKCS#7对象创建的附加接口定义。
//灵感来自OpenSSL的crl2p7.c文件。需要为函数返回清理一点。
%线程允许pkcs7创建退化;
%内联%{
int pkcs7创建退化(堆栈(X509)*证书堆栈,BIO*BIO){
int-ret=1;
PKCS7*p7=NULL;
PKCS7_SIGNED*p7s=NULL;
X509_CRL*CRL=NULL;
(X509_CRL)*CRL_堆栈的堆栈=NULL;
如果((p7=PKCS7_new())==NULL)转到结束;
如果((p7s=PKCS7_SIGNED_new())==NULL)转到结束;
p7->type=OBJ_nid2obj(NID_pkcs7_签名);
p7->d.sign=p7s;
p7s->contents->type=OBJ_nid2obj(NID_pkcs7_数据);
如果(!ASN1_INTEGER_set(p7s->version,1))转到结束;
如果((crl_stack=sk_X509_crl_new_null())==null)转到结束;
p7s->crl=crl\U堆栈;
p7s->cert=cert\u堆栈;
ret=i2d_PKCS7_bio(bio,第7页);
完:
p7s->cert=NULL;
如果(p7!=NULL){
//printf(“即将释放p7:”);
无PKCS7_(第7页);
//printf(“释放的。\n”);
}
返回ret;
}
%}
功能详细信息
该函数将X509堆栈指针和BIO指针作为输入,并返回一个表示成功的整数
X509堆栈指针需要指向包含要放入退化PKCS#7对象中的证书的堆栈
BIO指针需要指向一个空的BIO结构,该结构稍后将填充PKCS#7对象
使用上述函数的Python代码示例:
来自M2Crypto导入X509,BIO,m2
sk=X509.X509_堆栈()
证书=X509.加载证书('ra.crt')
num=sk.push(证书)
证书=X509。加载证书('ca.crt')
num=sk.push(证书)
#此时,X509堆栈包含2个证书。
打印('num:%d'%num)
#创建保存PKCS#7对象的BIO。
bio=bio.MemoryBuffer()
#请求创建退化PCKS#7对象。
ret=m2.pkcs7_创建_退化(sk._ptr(),bio._ptr())
#打开文件进行写入。
f=打开('deg.p7s','w')
#从BIO读取并写入文件。
b=bio.read()
f、 写(b)
#关闭文件。
f、 关闭()
您可以使用直接调用OpenSSL共享库函数来完成此操作 你看过吗?看过。M2Crypto的PKCS7类不像Ruby类那样有certificates
方法。write()仍然需要将PKCS7文件作为输入。创建一个新的SMIME文件只会输出一个空白SMIME文件。虽然链接可能会回答这个问题,但链接会发生变化,因此堆栈溢出倾向于不依赖它们。在这里包括答案的基本部分,并提供链接供参考。