SMIME.smime_load_pkcs7 (_bio): M2Crypto.SMIME.SMIME_Error: 无内容类型

发布于 2024-12-02 22:47:39 字数 1196 浏览 2 评论 0原文

我在加载 pkcs#7 文件时遇到问题,请您帮忙找出我做错了什么。

我使用 OpenSSL 0.9.8g(如 Ubuntu 9.4 中所示)运行 M2Crypto-0.21.1,并使用 SWIG 1.3.36 和 python 2.6.2 构建。

“python setup.py test --test-suite=tests.test_smime”运行 15 个测试,退出状态为“OK”;所以安装似乎没问题。

我使用数字签名程序创建了 PEM 格式的 pkcs#7 文件,并从命令行使用 OpenSSL 对其进行了测试:

openssl smime -verify -inform PEM -in mandato-PEM.p7m -noverify

打印信封(我签名的文本文件)中包含的内容和“验证成功”。所以 OpenSSL(与 M2Crypto 使用的版本相同)似乎喜欢我的文件。

然而,当我在 M2Crypto 中尝试相同的操作时,它一开始就卡住了:

p7, data = SMIME.smime_load_pkcs7('mandato-PEM.p7m')

我收到以下异常:

回溯(最近一次调用最后一次):
文件“./sign.py”,第 110 行,在  中
p7, 数据 = SMIME.smime_load_pkcs7('mandato-PEM.p7m') 
文件“/usr/local/lib/python2.6/dist-packages/M2Crypto-0.21.1-py2.6-linux-i686.egg/M2Crypto/SMIME.py”,第 91 行,在 smime_load_pkcs7 中
p7_ptr, bio_ptr = m2.smime_read_pkcs7(bio)
M2Crypto.SMIME.SMIME_Error:没有内容类型

虽然我在 Ubuntu 中找到了问题的信息(https://lists.ubuntu.com/archives/ubuntu-server-bugs/2010-July/038683.html),但在我看来,自从我构建以来,这不适用于此处手动最新的 M2Crypto 和测试套件工作正常。

任何帮助解决我的问题的帮助将不胜感激!

非常感谢

-芽

I have problems loading a pkcs#7 file and ask your help to figure out what I'm doing wrong.

I run M2Crypto-0.21.1 with OpenSSL 0.9.8g (as present in Ubuntu 9.4) and built with SWIG 1.3.36 and python 2.6.2.

"python setup.py test --test-suite=tests.test_smime" runs 15 tests with exit status "OK"; so the installation seems to be ok.

I created a pkcs#7 file in PEM format with a digital signature program and tested it with OpenSSL from the command line:

openssl smime -verify -inform PEM -in mandato-PEM.p7m -noverify

which prints the content contained in the envelope (a text file that I signed) and "Verification successful". So OpenSSL (same version as used by M2Crypto) seems to like my file.

However, when I try the same in M2Crypto, it chocks right in the beginning on:

p7, data = SMIME.smime_load_pkcs7('mandato-PEM.p7m')

I get the following exception:

Traceback (most recent call last):
File "./sign.py", line 110, in <module>
p7, data = SMIME.smime_load_pkcs7('mandato-PEM.p7m') 
File "/usr/local/lib/python2.6/dist-packages/M2Crypto-0.21.1-py2.6-linux-i686.egg/M2Crypto/SMIME.py", line 91, in smime_load_pkcs7
p7_ptr, bio_ptr = m2.smime_read_pkcs7(bio)
M2Crypto.SMIME.SMIME_Error: no content type

While I have found information of a problem in Ubuntu (https://lists.ubuntu.com/archives/ubuntu-server-bugs/2010-July/038683.html), it seems to me that this cannot apply here since I built the latest M2Crypto manually and the test suite works fine.

Any help in resolving my problem would be highly appreciated!

many thanks

-bud

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梓梦 2024-12-09 22:47:39

经过大量的努力,这里为遇到同样问题的其他人提供了解决方案。

我按照食谱 http://code.activestate.com/recipes/285211/ 和发现网上有很多讨论,只是“verify(p7)”[SMIME 方法] 是不正确的,而“verify(p7, data)”是正确的做法。

这仅适用于签名被分离的 SMIME 文档。我的 pkcs#7 文件以及所有其他意大利数字签名文档都是包含签名和文件内容(DER 格式)的 pkcs#7 信封。

必须按如下方式验证封装的 p7m 文件:

s=SMIME.SMIME()    
st = X509.X509_Store()   
st.load_info(trustedCAsPEMfileName)    
s.set_x509_store(st)    
p7bio = BIO.MemoryBuffer(p7strPEM)
p7 = SMIME.load_pkcs7_bio(p7bio)
certStack = p7.get0_signers(X509.X509_Stack())
s.set_x509_stack(certStack)
try:
    docContent = s.verify(p7)
except SMIME.PKCS7_Error, e:
    print "An exception occurred!!!!"
    print e

为了测试其是否有效,我编辑了 p7m 文件,使得签名不再验证,并且正确打印出“摘要失败”。

After a lot of sweat, here the solution for others who run into the same issue.

I was following the recipe http://code.activestate.com/recipes/285211/ and found many discussions on the web that just "verify(p7)" [method of SMIME] wasn't correct and "verify(p7, data)" was the right thing to do.

This applies only to SMIME documents where the signature is detached. My pkcs#7 file, and all other Italian digitally signed documents, are pkcs#7 envelopes that contain both the signature and the file content (in DER format).

Enveloped p7m files have to be verified as follows:

s=SMIME.SMIME()    
st = X509.X509_Store()   
st.load_info(trustedCAsPEMfileName)    
s.set_x509_store(st)    
p7bio = BIO.MemoryBuffer(p7strPEM)
p7 = SMIME.load_pkcs7_bio(p7bio)
certStack = p7.get0_signers(X509.X509_Stack())
s.set_x509_stack(certStack)
try:
    docContent = s.verify(p7)
except SMIME.PKCS7_Error, e:
    print "An exception occurred!!!!"
    print e

To test that this works, I edited the p7m file such that the signature doesn't verify anymore and it correctly prints out "digest failure".

晨曦÷微暖 2024-12-09 22:47:39

您还可以直接验证 .p7m 文件(附加 DER 格式),但需要通过 m2 直接调用 OpenSSL 从 DER 格式加载 PKCS #7 对象 (m2.pkcs7_read_bio_der(input_bio._ptr()) )因为 M2Crypto SMIME 模块内部没有此功能。有关建议的补丁,请参阅 SMIME.py 的小补丁

这里是示例代码:

import logging

from M2Crypto import SMIME, X509, m2, BIO

certstore_path = "/etc/ssl/certs/ca-certificates.crt"
file_descriptor = open('test_file.p7m', 'rb')
input_bio = BIO.File(file_descriptor)
signer = SMIME.SMIME()
cert_store = X509.X509_Store()
cert_store.load_info(certstore_path)
signer.set_x509_store(cert_store)
try: 
    p7 = SMIME.PKCS7(m2.pkcs7_read_bio_der(input_bio._ptr()), 1)
except SMIME.SMIME_Error, e:
    logging.error('load pkcs7 error: ' + str(e))
sk3 = p7.get0_signers(X509.X509_Stack())
signer.set_x509_stack(sk3)
data_bio = None
try:
    v = signer.verify(p7, data_bio)
except SMIME.SMIME_Error, e:
    logging.error('smime error: ' + str(e))
except SMIME.PKCS7_Error, e:
    logging.error('pkcs7 error: ' + str(e))

代码来源:pysmime core

You can also verify a .p7m file (attached DER format) directly but you need to load PKCS #7 object from DER format by m2 direct call to OpenSSL (m2.pkcs7_read_bio_der(input_bio._ptr())) because there is no function for this inside M2Crypto SMIME module. For a proposed patch see Small patch to SMIME.py.

Here a sample code:

import logging

from M2Crypto import SMIME, X509, m2, BIO

certstore_path = "/etc/ssl/certs/ca-certificates.crt"
file_descriptor = open('test_file.p7m', 'rb')
input_bio = BIO.File(file_descriptor)
signer = SMIME.SMIME()
cert_store = X509.X509_Store()
cert_store.load_info(certstore_path)
signer.set_x509_store(cert_store)
try: 
    p7 = SMIME.PKCS7(m2.pkcs7_read_bio_der(input_bio._ptr()), 1)
except SMIME.SMIME_Error, e:
    logging.error('load pkcs7 error: ' + str(e))
sk3 = p7.get0_signers(X509.X509_Stack())
signer.set_x509_stack(sk3)
data_bio = None
try:
    v = signer.verify(p7, data_bio)
except SMIME.SMIME_Error, e:
    logging.error('smime error: ' + str(e))
except SMIME.PKCS7_Error, e:
    logging.error('pkcs7 error: ' + str(e))

Code Source: pysmime core

梦在夏天 2024-12-09 22:47:39

如果您只想从 .p7m 文件中提取原始文件(无需验证),则需要使用 pip install M2Crypto 安装 M2Crypto (您可能必须运行 sudo apt-get install libssl -dev 之前),然后运行此 Python 代码:

from M2Crypto import BIO, SMIME, X509

# Load file in memory just to showcase BIO usage
with open('file.p7m', 'rb') as file:
    p7m = file.read()

smime = SMIME.SMIME()
smime.set_x509_store(X509.X509_Store())
smime.set_x509_stack(X509.X509_Stack())
original_file_content = smime.verify(
    SMIME.load_pkcs7_bio_der(BIO.MemoryBuffer(p7m)),
    flags=SMIME.PKCS7_NOVERIFY
)

您可以使用 SMIME.load_pkcs7,根据您的用例,SMIME.load_pkcs7_bioSMIME.load_pkcs7_der 而不是 SMIME.load_pkcs7_bio_der:内存中 (_bio) 或文件系统 .p7m 文件以及 PEM 或 DER (_der) 格式。

If you only want to extract the original file from the .p7m one (without verifying it), you need to install M2Crypto with pip install M2Crypto (you must probably run sudo apt-get install libssl-dev before) and then run this Python code:

from M2Crypto import BIO, SMIME, X509

# Load file in memory just to showcase BIO usage
with open('file.p7m', 'rb') as file:
    p7m = file.read()

smime = SMIME.SMIME()
smime.set_x509_store(X509.X509_Store())
smime.set_x509_stack(X509.X509_Stack())
original_file_content = smime.verify(
    SMIME.load_pkcs7_bio_der(BIO.MemoryBuffer(p7m)),
    flags=SMIME.PKCS7_NOVERIFY
)

You can use SMIME.load_pkcs7, SMIME.load_pkcs7_bio, SMIME.load_pkcs7_der instead of SMIME.load_pkcs7_bio_der according to your use case: in-memory (_bio) or on file system .p7m file, and PEM or DER (_der) format.

一梦等七年七年为一梦 2024-12-09 22:47:39

我发现签名和取消签名的最佳参考是此处的 M2Crypto 测试:

http:// svn.osafoundation.org/m2crypto/trunk/tests/test_smime.py

def test_sign(self):
    buf = BIO.MemoryBuffer(self.cleartext)
    s = SMIME.SMIME()
    s.load_key('tests/signer_key.pem', 'tests/signer.pem')
    p7 = s.sign(buf, SMIME.PKCS7_DETACHED)
    assert len(buf) == 0
    assert p7.type() == SMIME.PKCS7_SIGNED, p7.type()
    assert isinstance(p7, SMIME.PKCS7), p7
    out = BIO.MemoryBuffer()
    p7.write(out)

    buf = out.read()

    assert buf[:len('-----BEGIN PKCS7-----')] == '-----BEGIN PKCS7-----'
    buf = buf.strip()
    assert buf[-len('-----END PKCS7-----'):] == '-----END PKCS7-----', buf[-len('-----END PKCS7-----'):]
    assert len(buf) > len('-----END PKCS7-----') + len('-----BEGIN PKCS7-----')

    s.write(out, p7, BIO.MemoryBuffer(self.cleartext))
    return out

def test_verify(self):
    s = SMIME.SMIME()

    x509 = X509.load_cert('tests/signer.pem')
    sk = X509.X509_Stack()
    sk.push(x509)
    s.set_x509_stack(sk)

    st = X509.X509_Store()
    st.load_info('tests/ca.pem')
    s.set_x509_store(st)

    p7, data = SMIME.smime_load_pkcs7_bio(self.signed)

    assert isinstance(p7, SMIME.PKCS7), p7
    v = s.verify(p7, data)
    assert v == self.cleartext

    t = p7.get0_signers(sk)
    assert len(t) == 1
    assert t[0].as_pem() == x509.as_pem(), t[0].as_text()

注意文档(http://svn.osafoundation.org/m2crypto/trunk/doc/howto.smime.html)因为它没有更新。

请参阅此补丁:

https://bugzilla.osafoundation.org/show_bug.cgi?id=13020

The best reference I found to sign and unsign is the M2Crypto tests here:

http://svn.osafoundation.org/m2crypto/trunk/tests/test_smime.py

def test_sign(self):
    buf = BIO.MemoryBuffer(self.cleartext)
    s = SMIME.SMIME()
    s.load_key('tests/signer_key.pem', 'tests/signer.pem')
    p7 = s.sign(buf, SMIME.PKCS7_DETACHED)
    assert len(buf) == 0
    assert p7.type() == SMIME.PKCS7_SIGNED, p7.type()
    assert isinstance(p7, SMIME.PKCS7), p7
    out = BIO.MemoryBuffer()
    p7.write(out)

    buf = out.read()

    assert buf[:len('-----BEGIN PKCS7-----')] == '-----BEGIN PKCS7-----'
    buf = buf.strip()
    assert buf[-len('-----END PKCS7-----'):] == '-----END PKCS7-----', buf[-len('-----END PKCS7-----'):]
    assert len(buf) > len('-----END PKCS7-----') + len('-----BEGIN PKCS7-----')

    s.write(out, p7, BIO.MemoryBuffer(self.cleartext))
    return out

def test_verify(self):
    s = SMIME.SMIME()

    x509 = X509.load_cert('tests/signer.pem')
    sk = X509.X509_Stack()
    sk.push(x509)
    s.set_x509_stack(sk)

    st = X509.X509_Store()
    st.load_info('tests/ca.pem')
    s.set_x509_store(st)

    p7, data = SMIME.smime_load_pkcs7_bio(self.signed)

    assert isinstance(p7, SMIME.PKCS7), p7
    v = s.verify(p7, data)
    assert v == self.cleartext

    t = p7.get0_signers(sk)
    assert len(t) == 1
    assert t[0].as_pem() == x509.as_pem(), t[0].as_text()

Be carefull with the documentation (http://svn.osafoundation.org/m2crypto/trunk/doc/howto.smime.html) because it is not updated.

See this patch:

https://bugzilla.osafoundation.org/show_bug.cgi?id=13020

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文