如何使用c#和EWS服务进行签名和加密以及通过电子邮件发送电子邮件

时间:2019-01-24 01:32:18

标签: c# exchangewebservices smime

我很难弄清楚如何使用C#和EWS服务发送经过签名和加密的电子邮件。我的代码可以用于签名或加密,但不能同时用于两者。当我尝试同时进行加密并先签名后,在客户端电子邮件方面,我不满意。当我做相反的操作(先签名然后加密)时,整个内容都被弄乱了,而不是只显示相关的mime内容,甚至还得到了mime标头作为如下所示的内容

{

This is a multipart message in MIME format.

------=_NextPart_7f8933f4841248c5a83a4d6b4fb29122.968773
Content-Type: text/plain;
    charset="us-ascii"

Hello!
I am manually generated signed message 22.


------=_NextPart_7f8933f4841248c5a83a4d6b4fb29122.968773
Content-Type: text/html;
    charset="us-ascii"

<html><head/><body><p>Hello!</p><p>I am manually generated signed and Encrypted message. Both</p></body></html>

------=_NextPart_7f8933f4841248c5a83a4d6b4fb29122.968773

}

因此,我想知道我的代码中缺少哪一部分来解决此问题,并且能够同时对电子邮件进行签名和加密。

我曾经用过这样的代码:

{

public void TestEncryptedEmailTest(X509Certificate2 cert, 
                                   X509Certificate2 signCert, 
                                   string emailTo,
                                   string emailFrom,
                                   bool encrypt, 
                                   bool signEmail)
{
    string msgId;
    string boundary;
    EmailMessage mail;

    if (!encrypt && !signEmail)
        throw new ArgumentException("This method only can be executed when a message is either required for encryption or User signing or both");

    try
    {
        mail = new EmailMessage(GetService());
        mail.ItemClass = "IPM.Note.SMIME";
        msgId = Guid.NewGuid().ToString("N");
        boundary = "----=_NextPart_" + msgId + "." + (new Random(100)).Next(999999);
    }
    catch (Exception e)
    {
        throw;
    }

    var mimeHeaders = new StringBuilder("");
    mimeHeaders.AppendLine("From: " + emailFrom);
    mimeHeaders.AppendLine("To: " + emailTo);
    mimeHeaders.AppendLine("Subject: SMIME test subject " + (new Random(100)).Next(999));
    mimeHeaders.AppendLine("Message-ID:\n <" + msgId + "@vd-srv08r2-dc.vd-test.local>");
    mimeHeaders.AppendLine("Content-Language: en-US");
    mimeHeaders.AppendLine("Content-Type: application/pkcs7-mime; smime-type=signed-data; name=\"smime.p7m\"");
    mimeHeaders.AppendLine("Content-Disposition: attachment; filename=\"smime.p7m\"");
    mimeHeaders.AppendLine("Content-Transfer-Encoding: base64");
    mimeHeaders.AppendLine("MIME-Version: 1.0");
    mimeHeaders.AppendLine("");

    StringBuilder bodyContent = new StringBuilder("");

    bodyContent.AppendLine("Content-Type: multipart/alternative;");
    bodyContent.AppendLine("\tboundary=\"" + boundary + "\"");
    bodyContent.AppendLine("");
    bodyContent.AppendLine("This is a multipart message in MIME format.");
    bodyContent.AppendLine("");
    bodyContent.AppendLine("--" + boundary);
    bodyContent.AppendLine("Content-Type: text/plain;");
    bodyContent.AppendLine("\tcharset=\"us-ascii\"");
    bodyContent.AppendLine("");
    bodyContent.AppendLine("Hello!");
    bodyContent.AppendLine("I am manually generated signed message 22.");
    bodyContent.AppendLine("");
    bodyContent.AppendLine("");
    bodyContent.AppendLine("--" + boundary);
    bodyContent.AppendLine("Content-Type: text/html;");
    bodyContent.AppendLine("\tcharset=\"us-ascii\"");
    bodyContent.AppendLine("");
    bodyContent.AppendLine("<html><head/><body><p>Hello!</p><p>I am manually generated signed and encrypted message. Encrypted First</p></body></html>");
    bodyContent.AppendLine("");
    bodyContent.AppendLine("--" + boundary);

    // Encrypt the message body
    byte[] procBodyEncrypted;
    if (encrypt)
    {
        var bodyBytes = Encoding.UTF8.GetBytes(bodyContent.ToString());
        procBodyEncrypted = EncryptBodyContent(bodyBytes, signCert);
    }
    else
        procBodyEncrypted = Encoding.UTF8.GetBytes(bodyContent.ToString());

    byte[] bodySignedBytes;
    if (signEmail)
    {
        // Sign the Message body
        ContentInfo content = new ContentInfo(procBodyEncrypted);
        SignedCms signedCms = new SignedCms(content, false);
        CmsSigner signer = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, signCert);

        signedCms.ComputeSignature(signer);
        bodySignedBytes = signedCms.Encode();
        // -----------------------------------------------------
    }
    else
        bodySignedBytes = procBodyEncrypted;

    string mimeHeader = mimeHeaders.ToString();
    mimeHeader += Convert.ToBase64String(bodySignedBytes);

    // Set MimeContent 
    mail.MimeContent = new MimeContent(Encoding.UTF8.HeaderName, Encoding.UTF8.GetBytes(mimeHeader));
    mail.Send();
}

private byte[] EncryptBodyContent(byte[] bodyBytes, X509Certificate2 cert)
{
    //AlgorithmIdentifier rc4 = new AlgorithmIdentifier(new Oid(oids());
    ContentInfo envelopContent = new ContentInfo(bodyBytes);  // 3DES Encryption
    EnvelopedCms envelope = new EnvelopedCms(envelopContent);
    CmsRecipient recipient = new CmsRecipient(cert);
    envelope.Encrypt(recipient);

    return envelope.Encode();
}

}

0 个答案:

没有答案