繁体   English   中英

C# 如何使用 Bouncy Castle 而不是 x509certificate2 在 Asp.net 5 中使用 S/Mime

[英]C# How to S/Mime in Asp.net 5 with Bouncy Castle instead of x509certificate2

我成功地使用以下代码在最新的 Windows 服务器上发送了 S/Mime 电子邮件,但在 2012 Windows 服务器上却失败了。 我认为 2012 不支持较新的 AES 加密。

我将如何重写以下代码以将System.Security.Cryptography.X509Certificates.X509Certificate2()替换为 Bouncy Castle,同时还使用 MimeKit 和 Mailkit? 我尝试在 2012 年使用较旧的 DES3,但它因CryptoThrowHelper+WindowsCryptographicException: The specified.network password is not correct. 完全相同的代码在我的开发人员机器上的 Windows 10 上运行得很好。 最终我希望它在 Linux 容器中运行,而且我认为 Bouncy Castle 打字和说起来更有趣。 :)

var message = new MimeMessage(); // Using MimeKit, MailKit 
message.To.Add( new MailboxAddress("John Doe","jdoe@somewhere.com"));
message.From.Add( new MailboxAddress("Jane Doe","jndoe@somewhere.com"));
message.Headers.Add( "AS3-From", "PILM");
message.Headers.Add( "AS3-To", "SARS");
message.Date = DateTimeOffset.Now;
message.MessageId = "42";
message.Subject = "This is a subject";
message.Body = new TextPart("html") { Text = "This is a body" };

using (var context = new TemporarySecureMimeContext())
{   // TODO: Replace Microsoft Cryptography with BouncyCastle
    var cert = new System.Security.Cryptography
        .X509Certificates.X509Certificate2(
        @"c:\security\smime.p12", "VeryCoolPassword",
        System.Security.Cryptography.X509Certificates
            .X509KeyStorageFlags.EphemeralKeySet);

    var recip = new CmsRecipient(cert) {
        EncryptionAlgorithms = new EncryptionAlgorithm[] { 
            EncryptionAlgorithm.TripleDes }
    };
    var recips = new CmsRecipientCollection();
    recips.Add(recip);

    message.Body = ApplicationPkcs7Mime.Encrypt(
        context, recips, message.Body );
};

var client = new SmtpClient();
client.Connect("MySuperEmailServer", 465, true);
client.Authenticate("MySuperUserName", "VeryCoolPassword");
client.Send(message);
client.Disconnect(true);
client.Dispose();

这个问题似乎有几个部分。

首先,您想知道如何使用 BouncyCastle 加载 S/MIME 证书。 因为,正如 Crypt32 指出的那样,您不太可能需要加载 *.pfx(又名 *.p12)文件,因为您没有他们的私钥,您可能需要加载 *.cer(或 * .crt)文件:

using (var stream = File.OpenRead ("smime-recipient-certificate.cer")) {
    var parser = new X509CertificateParser ();

    var certificate = parser.ReadCertificate (stream);
}

如果您调用带有 fileName 参数的 CmsRecipient.ctor,MimeKit 的 CmsRecipient class 将为您执行此操作。

也就是说,如果您可能没有将它存储在磁盘上的某个地方(例如,可能是 MemoryStream 或其他东西),知道如何手动加载它永远不会有坏处。

采用 X509Certificate2(您当前正在使用)的 CmsRecipient.ctor 也可以使用。 MimeKit 只是在内部将 X509Certificate2 证书转换为 BouncyCastle 证书。

也就是说,根据您与 Crypt32 的对话,听起来您遇到的问题是从 Windows Server 2012 上的 a.pfx 文件加载 X509Certificate2? 在这种情况下,使用 BouncyCastle 加载证书可能是通往 go 的途径。

如果您需要或想知道如何使用 BouncyCastle 加载 .pfx 文件,您可以使用以下逻辑来实现:

// Note: BouncyCastle's X509Certificate class is named X509Certificate, not to be
// confused with System.Security.Cryptography.X509Certificates.X509Certificate.
X509Certificate LoadPfx (Stream stream, string password, out AsymmetricKeyParameter privateKey)
{
    var pkcs12 = new Pkcs12Store (stream, password.ToCharArray ());

    foreach (string alias in pkcs12.Aliases) {
        if (!pkcs12.IsKeyEntry (alias))
            continue;

        var chain = pkcs12.GetCertificateChain (alias);

        if (chain.Length == 0)
            continue;

        var keyEntry = pkcs12.GetKey (alias);

        if (!keyEntry.Key.IsPrivate)
            continue;

        privateKey = keyEntry.Key;

        return chain[0].Certificate;
    }

    throw Exception ("Did not find a certificate with a private key.");
}

注意:我可能会建议更改此设置:

message.MessageId = "42";

对此:

message.MessageId = MimeUtils.GenerateMessageId();

这将使用正确的语法生成随机/唯一的消息 ID 值(消息 ID header 不是数字,它是 xyz@abc.com 类型值)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM