Невозможно расшифровать p7m с помощью MimeKit

Я обнаружил свой 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();
    }
}

person codenamezero    schedule 19.12.2017    source источник
comment
Что содержит data? Держу пари, что это неподходящий контент для этого. Разберите сообщение с помощью MimeMessage.Load(), а затем найдите ApplicationPkcs7Mime BodyPart для проверки. Проверьте модульные тесты в репозитории MimeKit на github, чтобы увидеть примеры.   -  person jstedfast    schedule 20.12.2017
comment
data было вложением p7m, которое сначала считывалось как байт, а затем преобразовывалось в MemoryStream для преобразования в ApplicationPkcs7Mime.   -  person codenamezero    schedule 20.12.2017


Ответы (1)


Вы получаете InvalidOperationException, потому что вызываете Verify () для EncryptedData.

Вам нужно вызвать Decrypt ().

Verify () предназначен для SignedData.

person jstedfast    schedule 19.12.2017
comment
Спасибо, вы правы, я пробовал разные вещи и изначально кода не было CryptographyContext.Register. После того, как я добавил эту строку, я не стал возвращаться и пытаться Decrypt ее. - person codenamezero; 20.12.2017
comment
Можно ли воспроизвести результат MimeEntity и просто заменить его на p7m? Значение p7m = (ApplicationPkcs7Mime) p7m.Decrypt(ctx);. Только для того, чтобы я мог позвонить Verify по нему? - person codenamezero; 20.12.2017
comment
Если вы знаете, что расшифрованный контент является объектом ApplicationPkcs7Mime, да. - person jstedfast; 20.12.2017
comment
Могу ли я использовать MimeParser для анализа расшифрованного содержимого? Я получаю Failed to parse message headers. См. Обновленный вопрос. - person codenamezero; 21.12.2017
comment
Вы что-то делаете не так. Добавьте свой код, чтобы я мог видеть, что вы делаете. - person jstedfast; 21.12.2017
comment
Привет, jstedfast, пожалуйста, посмотрите обновленный вопрос. Кроме того, можно ли расшифровать НЕПОДПИСАННОЕ электронное письмо? Я попытался позвонить Decrypt на p7m, у которого нет сертификата / подписи (электронное письмо было отправлено из почтового клиента Mac, где они могли зашифровать без подписи). Прямо сейчас он возвращает null, когда я пытаюсь его расшифровать. - person codenamezero; 22.12.2017
comment
Verify () не расшифровывает, а просто извлекает исходный контент. Расшифровки нет. - person jstedfast; 22.12.2017
comment
Я понятия не имею, что вы спрашиваете о расшифровке неподписанного контента. Хм!?!?!? - person jstedfast; 22.12.2017
comment
В Apple Mac Mail вы можете отправлять неподписанные, но зашифрованные сообщения электронной почты. Используя MimeKit, я не смог это расшифровать. - person codenamezero; 22.12.2017
comment
В этом случае просто вызовите Decrypt (), а не Verify (). Вы делаете этот ПУТЬ более сложным, чем он есть на самом деле. - person jstedfast; 22.12.2017
comment
Я звоню Decrypt, но выкидываю The enveloped-data message does not contain the specified recipient. - person codenamezero; 22.12.2017
comment
Вероятно, это означает, что сообщение не было зашифровано ни для одного сертификата, для которого у вас есть закрытый ключ. - person jstedfast; 22.12.2017