You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Microsoft Graph发送数字签名电子邮件?(附现有代码)

使用Microsoft Graph发送带数字签名的邮件

要发送带数字签名的S/MIME邮件,Microsoft Graph要求你先在本地完成邮件的S/MIME签名,再将签名后的完整MIME内容通过Message.Raw属性提交,而非使用普通的Message对象构造方式。以下是具体实现步骤和代码:

关键前提

  • 发送邮件的用户邮箱已配置有效的S/MIME签名证书(可在Exchange管理中心或本地证书存储中获取)
  • 应用已拥有Mail.Send权限(你当前的代码已满足此条件)

实现步骤及代码

  1. 构造并签名邮件为S/MIME格式
    使用System.Security.Cryptography.Pkcs命名空间下的类完成签名,生成Base64编码的完整MIME邮件内容。

  2. 通过Graph发送签名后的邮件
    将签名后的Base64内容赋值给Message.Raw,调用SendMail接口发送。

完整代码示例:

using System;
using System.Collections.Generic;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Pkcs;
using System.Text;
using Azure.Identity;
using Microsoft.Graph;
using Microsoft.Graph.Models;

// 1. 获取签名证书(示例从本地证书存储获取,可根据实际情况调整)
X509Certificate2 signingCert = GetSigningCertificate();

// 2. 构造原始邮件的MIME内容
string mimeContent = ConstructMimeMessage(
    "Test Signed Email",
    "Some text",
    "sender@domain.com",
    "somebody@somewhere.com"
);

// 3. 对MIME内容进行S/MIME签名
string signedMimeBase64 = SignMimeContent(mimeContent, signingCert);

// 4. 使用Graph发送签名后的邮件
ClientSecretCredential credentials = new ClientSecretCredential(
    "--TenantId--",
    "--ClientId--",
    "--Secret--",
    new TokenCredentialOptions { AuthorityHost = AzureAuthorityHosts.AzurePublicCloud }
);

GraphServiceClient graphServiceClient = new GraphServiceClient(credentials);

Message signedMessage = new Message
{
    Raw = signedMimeBase64
};

await graphServiceClient
    .Users["--UserId--"]
    .SendMail(signedMessage, false)
    .Request()
    .PostAsync();

// 辅助方法:获取签名证书
X509Certificate2 GetSigningCertificate()
{
    using X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
    store.Open(OpenFlags.ReadOnly);
    X509Certificate2Collection certs = store.Certificates.Find(
        X509FindType.FindBySubjectName,
        "你的证书主题名称",
        validOnly: true
    );
    if (certs.Count == 0)
        throw new InvalidOperationException("未找到有效的签名证书");
    return certs[0];
}

// 辅助方法:构造基础MIME邮件内容
string ConstructMimeMessage(string subject, string body, string from, string to)
{
    StringBuilder mimeBuilder = new StringBuilder();
    mimeBuilder.AppendLine($"From: {from}");
    mimeBuilder.AppendLine($"To: {to}");
    mimeBuilder.AppendLine($"Subject: {subject}");
    mimeBuilder.AppendLine("MIME-Version: 1.0");
    mimeBuilder.AppendLine("Content-Type: text/html; charset=utf-8");
    mimeBuilder.AppendLine();
    mimeBuilder.AppendLine(body);
    return mimeBuilder.ToString();
}

// 辅助方法:对MIME内容进行S/MIME签名
string SignMimeContent(string mimeContent, X509Certificate2 signingCert)
{
    byte[] mimeBytes = Encoding.UTF8.GetBytes(mimeContent);
    ContentInfo contentInfo = new ContentInfo(mimeBytes);
    SignedCms signedCms = new SignedCms(contentInfo, detached: false);
    CmsSigner signer = new CmsSigner(signingCert);
    signedCms.ComputeSignature(signer);
    byte[] signedBytes = signedCms.Encode();
    return Convert.ToBase64String(signedBytes);
}

注意事项

  • detached: false表示签名是内嵌的,收件人可直接在邮件客户端看到签名验证结果
  • 确保签名证书的私钥可访问(如果是从文件加载,需确保证书包含私钥)
  • 若需要加密+签名,可先签名再加密,或先加密再签名(根据需求选择)

内容的提问来源于stack exchange,提问作者ChronosCZ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 18:45:33