Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Python输出仅限证书的PKCS#7_Python_Ruby_Openssl - Fatal编程技术网

如何使用Python输出仅限证书的PKCS#7

如何使用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 =

我正在用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 = 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对象

涉及的步骤如下:

  • 将M2Crypto从Martin Paljak的回购协议中转移到新的回购协议中
  • 修改
    \u pkcs7.i
    SWIG接口文件以添加以下功能
  • _pkcs7.i修改
    //添加与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文件。虽然链接可能会回答这个问题,但链接会发生变化,因此堆栈溢出倾向于不依赖它们。在这里包括答案的基本部分,并提供链接供参考。