我正在尝试在.NET Core应用中使用S/MIME
创建MimeKit
电子邮件。像这样的本地证书可以正常工作:
var signer = new CmsSigner("cert.pfx", "password");
message.Body = MultipartSigned.Create(ctx, signer, message.Body);
为了使应用程序更安全,我已将证书上传到Azure KeyVault。这是我的问题已经开始了。
该想法是仅使用Azure KeyVault的证书,而不使用任何密码等(因此,仅存储对KeyVault的引用,而不是存储两个链接(KeyVault cert + KeyVault certPass))。
这是我试图从Azure KeyVault获取证书的方式。
private static async Task<X509Certificate2> GetCertificate()
{
var tokenProvider = new AzureServiceTokenProvider();
var keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(tokenProvider.KeyVaultTokenCallback));
var azureKeyVaultCert = await keyVaultClient.GetSecretAsync("https://<myapp>.vault.azure.net/secrets/<secretName>/<secretId>");
var certBytes = Convert.FromBase64String(azureKeyVaultCert.Value);
var cert = new X509Certificate2(certBytes);
return cert;
}
然后:
var cert = new GetCertificate();
var signer = new CmsSigner(cert);
我在这里遇到这样的错误:MimeKit: 'RSACng' is currently not supported.
之后,我尝试了另一种方法。一切正常,但是,我需要使用密码。我认为这不是个好主意(尽管我也可以使用Azure KeyVault作为证书密码)。
private static async Task<byte[]> GetCertificateBytes()
{
var tokenProvider = new AzureServiceTokenProvider();
var keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(tokenProvider.KeyVaultTokenCallback));
var azureKeyVaultCert = await keyVaultClient.GetSecretAsync("https://<myapp>.vault.azure.net/secrets/<secretName>/<secretId>");
var certBytes = Convert.FromBase64String(azureKeyVaultCert.Value);
var certCollection = new X509Certificate2Collection();
certCollection.Import(certBytes, null, X509KeyStorageFlags.Exportable);
return certCollection.Export(X509ContentType.Pkcs12, "password");
}
var certBytes = await GetCertificateBytes();
using(var certStream = new System.IO.MemoryStream(certBytes))
{
var signer = new CmsSigner(certStream, "password");
}
如果我使用await keyVaultClient.GetCertificateAsync()
,我会收到一个错误,提示没有私钥。
此外,通过new X509Certificate2()
和X509Certificate2Collection.Export()
创建的证书也有所不同。
也许我想念什么?