使Outlook识别我的数字签名电子邮件

4

我正在使用C# .NET 4.0发送一个签名的SMTP邮件,代码如下:

    private void SendMailMessage(object data)
    {
        MailMessage message = new MailMessage();
        message.From = new MailAddress(fromAddress);
        message.To.Add(new MailAddress(emailTo));
        message.Subject = "Subject";
        message.IsBodyHtml = true;
        message.Body += "Blah blah blah.";
        byte[] messageBytes = Encoding.ASCII.GetBytes(message.Body);
        SignedCms Cms = new SignedCms(new ContentInfo(messageBytes));
        CmsSigner Signer = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, certificate);
        Cms.ComputeSignature(Signer);
        byte[] SignedBytes = Cms.Encode();
        MemoryStream signedStream = new MemoryStream(SignedBytes);
        AlternateView signedView = new AlternateView(signedStream, "application/pkcs7-mime; smime-type=signed-data;name=sig.p7m");
        message.AlternateViews.Add(signedView);
        SmtpClient client = new SmtpClient(smtpServer, int.Parse(smtpServerPort));
        client.DeliveryMethod = SmtpDeliveryMethod.Network;
        client.Send(message);
        message.Dispose();
        client = null;       
    }

据我所知,这在某种程度上是“可行的”,因为如果查看消息的原始数据,可以看到其中一个大的PKCS签名的备选视图。但是Outlook并不承认它。Outlook客户端通常会识别已签名的消息,并尝试验证它们,并在消息上放置一个小证书等等...
我想要那个... 我还缺少什么?
编辑:我自己在这方面取得了一些进展,但仍然遇到一些麻烦。现在代码看起来像这样:
    private void SendMailMessage(string emailTo)
    {            
        MailMessage message = new MailMessage();
        message.From = new MailAddress(fromAddress);
        message.To.Add(new MailAddress(emailTo));
        message.Subject = "Special Delivery";
        message.IsBodyHtml = false;
        string body = "Content-Type: text/plain;charset=\"iso-8859-1\"\nContent-Transfer-Encoding: quoted-printable\n\nHere is some body text!";
        byte[] messageBytes = Encoding.ASCII.GetBytes(body);
        ContentInfo content = new ContentInfo(messageBytes);
        SignedCms signedCms = new SignedCms(content, false);
        CmsSigner Signer = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, certificate);
        signedCms.ComputeSignature(Signer);
        byte[] signedBytes = signedCms.Encode();
        MemoryStream ms = new MemoryStream(signedBytes);
        AlternateView av = new AlternateView(ms, "application/pkcs7-mime; smime-type=signed-data;name=smime.p7m");
        message.AlternateViews.Add(av);
        SmtpClient client = new SmtpClient(smtpServer, int.Parse(smtpServerPort));
        client.DeliveryMethod = SmtpDeliveryMethod.Network;
        client.Send(message);
        message.Dispose();
        client = null;
    }

值得注意的是,这次我留空了消息正文 message.Body,仅发送了 AlternateView。现在,当我将其发送到 Outlook 邮箱时,会在我的电子邮件上显示一个挂锁图标,S/MIME 小玩意儿会尝试验证签名者,但失败了。用于签署电子邮件的证书由公共可信 CA 发行。 编辑:这是我的问题,证书没有“安全电子邮件”使用属性。我会获取新的证书。

当我将相同的电子邮件发送到 Gmail 地址时,我会收到一个带有*.p7m附件的空白消息,其中包含一堆垃圾。

1个回答

6

在Outlook中使其工作的代码如下:

private void SendMailMessage(string emailTo)
{
    MailMessage message = new MailMessage();
    message.From = new MailAddress(fromAddress);
    message.To.Add(new MailAddress(emailTo));
    message.Subject = "Regarding your lottery winnings";
    message.IsBodyHtml = false;
    string body = "Content-Type: text/plain;charset=\"iso-8859-1\"\nContent-Transfer-Encoding: quoted-printable\n\nBlah blah blah blah blah blah.";                
    byte[] messageBytes = Encoding.ASCII.GetBytes(body);
    ContentInfo content = new ContentInfo(messageBytes);
    SignedCms signedCms = new SignedCms(content, false);
    CmsSigner Signer = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, emailCert);
    signedCms.ComputeSignature(Signer);
    byte[] signedBytes = signedCms.Encode();
    MemoryStream ms = new MemoryStream(signedBytes);
    AlternateView av = new AlternateView(ms, "application/pkcs7-mime; smime-type=signed-data;name=smime.p7m");
    message.AlternateViews.Add(av);                
    SmtpClient client = new SmtpClient(smtpServer, int.Parse(smtpServerPort));
    client.DeliveryMethod = SmtpDeliveryMethod.Network;
    client.Send(message);
    message.Dispose();
    client = null;
}

当然需要使用有效证书。现在,当我发送这封电子邮件并在Outlook中查看它时,会在邮件上显示证书图标,并且S/MIME控件成功验证签名,在不向用户显示标题的情况下,文本会按照我的要求显示出来。
请注意,必须保留message.Body为空。如果在message.Body中加入任何内容,它都会出错。

更新一个老问题,但是你怎么获取接收者的证书? - David Gomes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接