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 doodad が起動して署名者を確認しようとしますが、失敗します。電子メールの署名に使用される証明書は、公的に信頼された CA によって発行されます。 編集:それは私のせいです。証明書には「安全な電子メール」使用属性がありませんでした。新しい証明書を取得します。

同じメールを Gmail アドレスに送信すると、大量のゴミを含む *.p7m が添付された空のメッセージが届きます。

4

1 に答える 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 を空のままにしておく必要があることに注意してください。メッセージに何かを入れると、本文が壊れます。

于 2013-04-13T21:00:22.290 に答える