我很难弄清楚如何使用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();
}
}