我正在开发一个更大的应用程序,该应用程序通过POP3、IMAP或从.msg文件导入(从Outlook导出或从Outlook拖动(来接收电子邮件。
最近我收到一封电子邮件,附件是"smime.p7m"。经过进一步检查,它原来是一条带有的MIME消息
内容类型:多部分/签名;protocol="application/x-pkcs7-签名";
在其他部分中,它包含一部分
内容类型:application/x-pkcs7-签名;name="smime.p7s"内容传输编码:base64内容处置:附件;filename="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哈希值不正确。
如何验证签名?
有更好的方法吗?
要做到这一点,最简单的方法是使用MimeKit(它不仅是开源的,而且可以免费用于商业用途(。
由于您所关心的只是验证签名,因此您可以使用MimeKit.Cryptography.TemporarySecureMimeContext
,而不是设置自己的签名(就像README和其他文档中谈到的那样(。
通常,当您收到通过S/MIME签名的消息时,它几乎总是根级别的MIME部分,即multipart/signed
部分,这使得这在某种程度上更容易(验证签名的第一步是定位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.