无法使用 MimeKit 解密 p7m
Posted
技术标签:
【中文标题】无法使用 MimeKit 解密 p7m【英文标题】:Unable to decrypt p7m using MimeKit 【发布时间】:2018-06-02 08:28:37 【问题描述】:我从我的电子邮件信息中找到了我的smime.p7m
,我将其作为流读取并尝试使用 MimeKit 对其进行解密,但使用 Operation is not valid due to the current state of the object.
失败
using (MemoryStream ms = new MemoryStream(data))
CryptographyContext.Register(typeof(WindowsSecureMimeContext));
ApplicationPkcs7Mime p7m = new ApplicationPkcs7Mime(SecureMimeType.EnvelopedData, ms);
var ctx = new WindowsSecureMimeContext(StoreLocation.CurrentUser);
p7m.Verify(ctx, out MimeEntity output);
遵循https://github.com/jstedfast/MimeKit 上的示例也无济于事。任何熟悉 MimeKit 的人都可以插话吗?
编辑:
解密p7m后,我应该使用MimeParser
来解析内容吗?我从解密中得到以下信息:
Content-Type: application/x-pkcs7-mime; name=smime.p7m; smime-type=signed-data
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename=smime.p7m
MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAaCAJIAEWUNvbnRl
bnQtVHlwZTogdGV4dC9wbGFpbjsNCgljaGFyc2V0PSJ1cy1hc2NpaSINCkNvbnRlbnQtVHJhbnNm
ZXItRW5jb2Rpbmc6IDdiaXQNCg0KdGVzdA0KAAAAAAAAoIImTTCCBaIwggOKoAMCAQICBguC3JQz
...more...
但是当用MimeParser
解析时,
System.FormatException: Failed to parse message headers.
at MimeKit.MimeParser.ParseMessage(Byte* inbuf, CancellationToken cancellationToken)
at MimeKit.MimeParser.ParseMessage(CancellationToken cancellationToken)
更新:
啊,原来如此,调用Decrypt
只会给我SignedData
,然后我需要调用Verify 来提取原始数据......这有点误导,我认为Verify
会简单地验证它...这就是为什么我不费心打电话给它的原因,因为我真的不需要验证它...也许应该打电话给Decode
?这就是我最初想要做的,((MimePart) signedData).Content.DecodeTo(...)
。
所以最后,我不得不做这样的事情来提取数据。
CryptographyContext.Register(typeof(WindowsSecureMimeContext));
ApplicationPkcs7Mime p7m = new ApplicationPkcs7Mime(SecureMimeType.EnvelopedData, ms);
var ctx = new WindowsSecureMimeContext(StoreLocation.CurrentUser);
if (p7m != null && p7m.SecureMimeType == SecureMimeType.EnvelopedData)
// the top-level MIME part of the message is encrypted using S/MIME
p7m = p7m.Decrypt() as ApplicationPkcs7Mime;
if (p7m != null && p7m.SecureMimeType == SecureMimeType.SignedData)
p7m.Verify(out MimeEntity original); // THE REAL DECRYPTED DATA
using (MemoryStream dump = new MemoryStream())
original.WriteTo(dump);
decrypted = dump.GetBuffer();
【问题讨论】:
data
包含什么?我打赌这不是正确的内容。使用MimeMessage.Load()
解析消息,然后找到ApplicationPkcs7Mime
BodyPart
进行验证。检查 MimeKit 的 github 存储库中的单元测试以查看示例。
data
是 p7m 附件,它首先被读取为字节,然后转换为 MemoryStream
,以便将其转换为 ApplicationPkcs7Mime
。
【参考方案1】:
您收到 InvalidOperationException 是因为您在 EncryptedData 上调用 Verify()。
你需要调用 Decrypt()。
Verify() 用于 SignedData。
【讨论】:
谢谢你,你是对的,我尝试了各种不同的东西,最初没有代码CryptographyContext.Register
。添加该行后,我没有回去尝试Decrypt
它。
如果我将输出MimeEntity
替换为p7m
可以吗?意思是p7m = (ApplicationPkcs7Mime) p7m.Decrypt(ctx);
。只是为了让我可以打电话给Verify
?
如果你知道解密后的内容是一个ApplicationPkcs7Mime对象,是的。
我应该使用MimeParser
来解析解密的内容吗?我收到了Failed to parse message headers.
查看更新的问题。
你做错了什么。请添加您的代码,以便我看到您在做什么。以上是关于无法使用 MimeKit 解密 p7m的主要内容,如果未能解决你的问题,请参考以下文章
用于解密 SMIME.p7m 文件的 Javascript 库
如何使用公钥加密字符串并使用 MimeKit 使用私钥解密?
MIMEKIT Multipart Signed.Verify 如何禁用证书吊销列表检查?