【问题标题】:s/mime signed message cannot be open by outlookOutlook 无法打开 s/mime 签名的邮件
【发布时间】:2021-03-08 12:31:52
【问题描述】:

我需要使用 s/mime 对电子邮件进行数字签名。我为我的附件创建了一个分离的签名,但 Outlook 无法打开它:“无法打开此项目。基础安全系统无法找到您的数字 ID 名称”。证书已安装在此 PC 上,需要在此代码中进行调整:

const int CHARS_IN_LINE = 64;

StringBuilder message = new StringBuilder();
message.AppendLine("Content-Type: multipart/signed; protocol=\"application/pkcs7-signature\";");
message.AppendLine(" boundary=\"__multipart-signed-boundary__\"");
message.AppendLine("Content-Transfer-Encoding: 7bit");
message.AppendLine("MIME-Version: 1.0");
message.AppendLine("Subject: " + tbMessageSubject.Text);
message.AppendLine();
message.AppendLine("--__multipart-signed-boundary__");
message.AppendLine("Content-Type: text/xml; charset=\"windows - 1251\"");
message.AppendLine("Content-Disposition: attachment; ");
message.AppendLine(" filename=\"" + Path.GetFileName(filename) + "\"");
message.AppendLine("Content-Transfer-Encoding: base64");
message.AppendLine();

var dataToSign = File.ReadAllBytes(filePath);

var base64Data = Convert.ToBase64String(dataToSign, Base64FormattingOptions.None);
var base64DataSb = new StringBuilder(base64Data);
for (int i = CHARS_IN_LINE; i < base64DataSb.Length; i += CHARS_IN_LINE + 2) // \r\n
    base64DataSb.Insert(i, "\r\n");

message.AppendLine(base64DataSb.ToString());

message.AppendLine("--__multipart-signed-boundary__");
message.AppendLine("Content-Type: application/pkcs7-signature; name=\"smime.p7m\"");
message.AppendLine("Content-Transfer-Encoding: base64");
message.AppendLine("Content-Disposition: attachment; filename=smime.p7s");
message.AppendLine();

CmsSigner signer = new CmsSigner(clientCert);
SignedCms cms = new SignedCms(new ContentInfo(dataToSign), true);
cms.ComputeSignature(signer);

var signature = cms.Encode();

var base64Signature = Convert.ToBase64String(signature, Base64FormattingOptions.None);
var base64Sb = new StringBuilder(base64Signature);

for (int i = CHARS_IN_LINE; i < base64Sb.Length; i += CHARS_IN_LINE + 2) // \r\n
    base64Sb.Insert(i, "\r\n");

message.AppendLine(base64Sb.ToString());
message.AppendLine();
message.AppendLine("--__multipart-signed-boundary__--");
message.AppendLine(".");

var stream = new MemoryStream(Encoding.ASCII.GetBytes(message.ToString()));

MailMessage mail = new MailMessage();
mail.From = new MailAddress(tbEmailFrom.Text);
mail.To.Add(new MailAddress(tbEmailTo.Text));
AlternateView alternateView = new AlternateView(stream, "application/pkcs7-mime; smime-type=signed-data; name=smime.p7m");
alternateView.TransferEncoding = TransferEncoding.SevenBit;
mail.AlternateViews.Add(alternateView);

SmtpClient client = new SmtpClient(host, port);
client.EnableSsl = chbUseSSL.Checked;
client.Send(mail);

【问题讨论】:

  • 通过 Outlook 签名/加密消息工作正常。但没有使用我上面的代码...
  • 谢谢,我已经看过这篇文章了,除了标题的一些变化外,它几乎和我的一样
  • 您是否使用与证书中相同的加密模式?您在发布的代码中是否有任何异常?添加尝试/捕获。如果您发送没有附件的电子邮件,上述代码是否有效?

标签: c# smtpclient sign smime skpsmtpmessage


【解决方案1】:

最后,问题出在 AlternateView 中指定的 mediaType 上,正确的方法:

AlternateView alternateView = new AlternateView(stream, "multipart/signed; protocol=\"application/pkcs7-signature\"; boundary=\"__multipart-signed-boundary__\"");
alternateView.TransferEncoding = TransferEncoding.SevenBit;

感谢jdweng,我需要签署的不是附件,而是带有标题的附件(第一个__multipart-signed-boundary 带有附件)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-18
    • 2014-11-14
    • 2014-10-29
    • 2017-03-02
    • 2012-05-15
    • 2019-09-03
    • 2011-02-10
    • 2011-04-25
    相关资源
    最近更新 更多