3

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();
    }
}
4

1 回答 1

4

您收到 InvalidOperationException 是因为您在 EncryptedData 上调用 Verify()。

您需要调用 Decrypt()。

Verify() 用于 SignedData。

于 2017-12-19T23:38:04.330 回答