如何验证SMIME multipart / signed application / x-pkcs7-signature Mail的签名

时间:2015-07-02 11:33:59

标签: c# smime openpop

我正在开发一个更大的应用程序,它通过POP3,IMAP或从.msg文件导入电子邮件(从Outlook导出或从Outlook拖出)。

最近我收到了一封附有“smime.p7m”附件的电子邮件。 经过进一步检查后,结果是一条带有

的MIME消息
  

内容类型:multipart / signed;   协议= “应用程序/ x-PKCS7签名”;

其他部分包含一个部分

  

Content-Type:application / x-pkcs7-signature; NAME = “smime.p7s”   Content-Transfer-Encoding:base64 Content-Disposition:attachment;   文件名= “smime.p7s”

我尝试使用OpenPop作为MIME消息解析器验证此签名,并SignedCms检查签名。我的尝试看起来像这样:

var datapart = OpenPop.MessagePart[...];
var part3 = OpenPop.MessagePart[3]; // the signature

var ci = new ContentInfo(datapart);            
var sCMS = new SignedCms(ci, detached: true);
sCMS.Decode(part3.Body);
sCMS.CheckHash();

sCMS.CheckSignature(verifySignatureOnly:true);

但不管我用于datapart的是什么,我总是得到

  

System.Security.Cryptography.CryptographicException   哈希值不正确。

如何验证签名?

有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

最简单的方法是使用MimeKit(不仅是开源的,而且还可以免费用于商业用途)。

由于你所关心的只是验证签名,你可以使用MimeKit.Cryptography.TemporarySecureMimeContext而不是自己设置(就像README和其他文档谈到的那样)。

通常,当您收到通过S / MIME签名的邮件时,它几乎总是作为multipart/signed部分的根级MIME部分,这使得这更容易一些(验证签名的第一步是找到multipart/signed部分。

var signed = message.Body as MultipartSigned;
if (signed != null) {
    using (var ctx = new TemporaryMimeContext ()) {
        foreach (var signature in signed.Verify (ctx)) {
            try {
                bool valid = signature.Verify ();

                // If valid is true, then it signifies that the signed
                // content has not been modified since this particular
                // signer signed the content.
                //
                // However, if it is false, then it indicates that the
                // signed content has
                // been modified.
            } catch (DigitalSignatureVerifyException) {
                // There was an error verifying the signature.
            }
        }
    }
}

您可以在www.mimekit.net/docs找到MimeKit的API文档。