Отправить зашифрованное и подписанное письмо, используя C # - PullRequest
3 голосов
/ 01 декабря 2010

Я хочу отправлять зашифрованные и подписанные письма без использования сторонних API.Если я отправляю только альтернативное представление с подписью, Почта Windows может проверить его.Если я отправляю только с альтернативным видом с зашифрованными данными, Почта Windows может расшифровать его.Но если я отправлю оба, Windows Mail получит 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("emailaddress@xpto.com", "XXXXXX");
SmtpClient client = new SmtpClient("smtp.xpto.com");

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

client.Send(message);

Label2.Text = "Assinado e cifrado!";

1 Ответ

4 голосов
/ 01 декабря 2010

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

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


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

...