Отправить зашифрованное и подписанное электронное письмо с помощью C #

Я хочу отправить зашифрованное и подписанное письмо без использования стороннего API. Если я отправлю только альтернативное представление с подписью, Почта Windows сможет его проверить. Если я отправлю только с альтернативным представлением с зашифрованными данными, Почта Windows сможет их расшифровать. Но если я отправлю оба, Почта Windows получит 2 вложения. Если я подписываю encryptedBytes и добавляю эти подписанные байты в альтернативное представление, он проверяет только подпись, а сообщение пустое. Любая идея?

MailMessage message = new MailMessage();
message.From = new MailAddress(lblMail.Text);
message.Subject = txtSubject.Text;

string body = "Content-Type: text/plain\r\nContent-Transfer-Encoding: 7Bit\r\n\r\n" + structForm();

byte[] messageData = Encoding.ASCII.GetBytes(body);
ContentInfo content = new ContentInfo(messageData);
EnvelopedCms envelopedCms = new EnvelopedCms(content);

message.To.Add(new MailAddress(provMail));

CmsRecipient recipient = new CmsRecipient(SubjectIdentifierType.SubjectKeyIdentifier, this.certificate);
envelopedCms.Encrypt(recipient);

byte[] encryptedBytes = envelopedCms.Encode();

SignedCms Cms = new SignedCms(new ContentInfo(encryptedBytes));
CmsSigner Signer = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, new X509Certificate2(@"c:\serv.pfx","123"));

Cms.ComputeSignature(Signer);
byte[] SignedBytes = Cms.Encode();

MemoryStream encryptedStream = new MemoryStream(encryptedBytes);
AlternateView encryptedView = new AlternateView(encryptedStream, "application/pkcs7-mime; smime-type=signed--data;name=smime.p7m");
message.AlternateViews.Add(encryptedView);
MemoryStream signedStream = new MemoryStream(SignedBytes);
AlternateView signedView = new AlternateView(signedStream, "application/pkcs7-mime; smime-type=signed-data;name=sig.p7m");
message.AlternateViews.Add(signedView);


System.Net.NetworkCredential SMTPUserInfo = new System.Net.NetworkCredential("[email protected]", "XXXXXX");
SmtpClient client = new SmtpClient("smtp.xpto.com");

client.UseDefaultCredentials = false;
client.Credentials = SMTPUserInfo;

client.Send(message);

Label2.Text = "Assinado e cifrado!";

person Miguel Ribeiro    schedule 01.12.2010    source источник


Ответы (1)


Вы должны сначала подписать, а затем зашифровать.

Хотя исходные спецификации CMS и S / MIME позволяют выполнять операции в любом порядке, более поздние исследования показали, что подписание документа, который вы не можете прочитать, - действительно плохая идея. Подпись должна быть поверх обычного текста.


Результирующее сообщение MIME должно иметь только одну часть, которая должна быть данными в оболочке S / MIME. Ваше сообщение состоит из двух частей, и зашифрованная часть неправильно помечена типом содержимого подписанных данных. Создайте и подпишите объект SignedCms. Закодируйте его и используйте закодированное значение как содержимое объекта EnvelopedCms. Зашифруйте это и используйте его закодированное значение в качестве содержимого вашего MailMessage с типом содержимого «application / pkcs7-mime; smime-type = enveloped-data».

person erickson    schedule 01.12.2010
comment
Итак, я поставил сделанную подпись перед шифрованием. Однако это все тот же эффект. Если я отправлю только подпись + шифрование, это не сработает - person Miguel Ribeiro; 01.12.2010
comment
Я верю, что вы говорите сделать что-то подобное? pastebin.com/g1q6fkJL (извините .. комментарии не принимают код ...) Я пробовал этот способ и, после сообщения получаются скомбинированные символы ... - person Miguel Ribeiro; 02.12.2010