簡體   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