我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
只是验证它......这就是为什么我没有打扰调用它,因为我真的不需要验证它......也许应该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();
}
}