m2crypto与openssl行为不一致

1 投票
3 回答
1143 浏览
提问于 2025-04-16 00:34

我需要把一堆bash脚本整合起来,可能还要重写,这些脚本的作用是验证收到的smime消息是否有效(也就是说,这些消息是用公司的私钥加密的,并且是用特定的一组公钥签名的)。

这堆bash脚本将会被一个小应用程序替代,可能会用Python编写,并借助M2Crypto这个库。

到目前为止,解密的部分进展得很顺利,但我在签名验证上遇到了问题。

我需要写一段Python代码来替代这一行bash命令:

 openssl smime -verify -in to_verify.txt -CAfile signer_pubkey.pem -out verified.txt

to_verify.txt的内容是“常见的”multipart/signed p7格式,里面可能附带签名,也可能没有。

之前的命令在验证成功时会返回0,并从smime信封中提取内容。

现在,回到Python,参考m2crypto的例子:

import os
from M2Crypto import BIO, Rand, SMIME, X509
cert_dir = '/home/niphlod/certs'
doc_dir = '/home/niphlod/datastore'

signer = os.path.join(cert_dir, 'signer_pubkey.pem')
letter = os.path.join(doc_dir,'out_decrypt.txt')

# Instantiate an SMIME object.
s = SMIME.SMIME()

# Load the signer's cert. 
x509 = X509.load_cert(signer)
sk = X509.X509_Stack()
sk.push(x509)
s.set_x509_stack(sk)

# Load the signer's CA cert. They're all self-signed, hence the following
st = X509.X509_Store()
st.load_info(signer)
s.set_x509_store(st)

# Load the data, verify it.
p7, data = SMIME.smime_load_pkcs7(letter)
v = s.verify(p7)
print v
print data
print data.read()

结果让我很惊讶,我得到了:

Traceback (most recent call last):
  File "m2crypto_verify.py", line 28, in <module>
    v = s.verify(p7)
  File "/usr/lib/pymodules/python2.6/M2Crypto/SMIME.py", line 215, in verify
    blob = m2.pkcs7_verify0(p7, self.x509_stack._ptr(), self.x509_store._ptr(), flags)
M2Crypto.SMIME.PKCS7_Error: no content

OpenSSL能够正确读取、提取和验证这些文件,但为什么m2crypto却报告说没有内容呢?

补充一下:没有人对此感兴趣吗?

3 个回答

0

这是我用来进行S/Mime验证的机制,使用的是M2Crypto这个库。

# Load the data
#
try:
  p7, data = SMIME.smime_load_pkcs7( letter )
except SMIME.SMIME_Error, e:
  print 'Error: could not load {file} because {error}'.format(file=letter,error=e)
  sys.exit()

# Verify the data
#
try:
  if data is not None:
    v = s.verify(p7, data)
  else:
    v = s.verify(p7)
  if v:
    print 'Client signature verified'
except SMIME.SMIME_Error, e:
  print 'Error: message verification failed %s' % e
0

凯文的回答是对的。

    v = s.verify(p7,data)

verify() 方法需要比较签名消息的两个部分(明文和加密后的内容)。

这个函数需要几个参数,具体可以在 M2Crypto 的文档 中找到。它会调用 openssl 的 PKCS7_verify 方法,详细信息可以在 OpenSSL 的文档 中查看。很遗憾的是,M2Crypto 的教程中包含了一些错误的默认值(至少在我使用的 v0.20.1 版本中是这样的)。

0

我之前遇到过类似的问题,使用的是M2Crypto v0.17。我通过修改这一行:

 v= s.verify(p7)

变成了:

 v = s.verify(p7,data)

撰写回答