Отправить зашифрованное письмо с вложениями (asp. net mvc, C#) - PullRequest
1 голос
/ 20 февраля 2020

Это кажется трудным найти хороший ответ. Я хочу создать почтовое сообщение, добавить в него вложения, зашифровать его с помощью сертификата X509Certificate2, а затем отправить его. Звучит достаточно просто, правда ?! Я использую asp. net mvc и C#.

Это то, что у меня есть до сих пор.

string sMTPClient = ConfigurationManager.AppSettings.Get("SMTPClient");
        using (var smtpClient = new SmtpClient(sMTPClient))
        {
            var attachments = MethodToCreateMailAttachments(......);
            X509Certificate2 certificate = MethodToGetCertificateBySerialNumber("xxxxxxx");

            using (var finalMailmessage = new MailMessage())
            {
                var encryptedMailMessage = new MailMessage();
                var encryptCert = new X509Certificate2(certificate);
                encryptedMailMessage.Subject = mailsubject;
                encryptedMailMessage.Body = mailBody;
                if (attachments.Any())
                {
                    foreach (var item in attachments)
                        encryptedMailMessage.Attachments.Add(item);
                }

                byte[] encryptedBodyBytes = Encoding.ASCII.GetBytes(encryptedMailMessage.ToString());

                EnvelopedCms Envelope = new EnvelopedCms(new ContentInfo(encryptedBodyBytes));
                CmsRecipient Recipient = new CmsRecipient(SubjectIdentifierType.IssuerAndSerialNumber, encryptCert);
                Envelope.Encrypt(Recipient);
                byte[] EncryptedBytes = Envelope.Encode();

                //Attach the encrypted message as an alternate view.
                MemoryStream ms = new MemoryStream(EncryptedBytes);
                AlternateView av = new AlternateView(ms, "application/pkcs7-mime; smime-type=signed-data;name=smime.p7m");
                finalMailmessage.AlternateViews.Add(av);

                finalMailmessage.From = new MailAddress(mailFrom);

                foreach (var address in mailTo.Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries))
                {
                    finalMailmessage.To.Add(address);
                }

                var smtp = new SmtpClient(sMTPClient);
                smtp.Send(finalMailmessage);
                finalMailmessage.Dispose();
                ErrorLogging.log.Debug("Mailmessage sent");
                return "";
            }
        }

То, что это делает, это создает два MailMessages, один для вещи, которые должны быть зашифрованы, вложения, тело и тема. Затем я создаю сообщение, которое будет отправлено. К этому я добавляю первое сообщение как альтернативный вид. Это работает настолько, что зашифровывает и отправляет электронную почту, и в конце я получаю электронное письмо со значком замка в Outlook.

Затем я могу открыть сообщение в Outlook, импортировав сертификат. Это работает. Однако рядом со значком замка в Outlook появляется значок вложения скрепки, который указывает на то, что к сообщению прикреплено что-то. Но сообщение пусто. Так что ничего не привязывается, по-видимому. Я подозреваю, что добавление зашифрованного MailMessage в качестве альтернативного представления к другому MailMessage, вот где я ошибся.

Я пробовал много других вещей без удачи, и это самое близкое, что у меня есть прийти к рабочему решению. Мне нужен вклад, так что у кого-нибудь есть предложения?

1 Ответ

1 голос
/ 21 февраля 2020

Я нашел рабочее решение. Проблема была в этой части:

byte[] encryptedBodyBytes = Encoding.ASCII.GetBytes(encryptedMailMessage.ToString());

Мне пришлось создать поток памяти, который затем можно преобразовать в байтовый массив. Я использовал инструмент под названием «MimeKit», который можно установить как пакет nuget.

Итак, вместо этого у меня есть:

var memStream = new MemoryStream();
var mimeMessage = MimeMessage.CreateFromMailMessage(encryptedMailMessage);
mimeMessage.WriteTo(memStream);
var messageString = Encoding.UTF8.GetString(memoryStream.ToArray());
byte[] encryptedBodyBytes = Encoding.ASCII.GetBytes(messageString);

Остальное тоже самое.

...