繁体   English   中英

如何获取私钥作为从 azure 密钥库中获取的受密码保护的 pfx 的字节 []

[英]How to get private key as Byte[] of a password protected pfx fetched from azure key vault

我正在使用 GetSecretAsync() 方法从 Azure Key Vault 获取我的证书,然后我期望最终获得私钥和证书的字节 []。

我的应用程序在 .netcore3.1 这就是我的代码的样子:

var certWithPrivateKey = Client.GetSecretAsync(ConfigurationSettings.AppSettings["AKVEndpoint"], ConfigurationSettings.AppSettings["CertName"]).GetAwaiter().GetResult();
var privateKeyBytes = Convert.FromBase64String(certWithPrivateKey.Value);

X509Certificate2 x509Certificate = new X509Certificate2(privateKeyBytes);
var privateKey = x509Certificate.GetRSAPrivateKey() as RSA;

我得到了 RSACng 类型的有效 privateKey,但任何操作(尝试 ExportRSAPrivateKey())都会引发“'privateKey.ExportRSAPrivateKey()' 类型的异常”和“The不支持请求的操作。”

我不确定接下来如何继续获取私钥和证书的字节 []。

由于您实际上似乎需要导出:您当前的代码不会将私钥加载为可导出的,因此无法导出。 解决方法是断言可导出性:

X509Certificate2 x509Certificate =
    new X509Certificate2(privateKeyBytes, "", X509KeyStorageFlags.Exportable);

如果这还不够,那么您会遇到 CAPI 可导出性和 CNG 可导出性(Windows 较旧和较新的加密库)之间的差异。 如果来自 PFX/PKCS#12 的私钥被加载到 CNG 中,它只是“加密的可导出”,但 ExportParameters 是明文导出。

不过,有一种解决方法...将其加密导出,然后使用更灵活的导出策略将其导入其他地方,然后再次导出。

This snippet uses the .NET Core 3.0+ ExportPkcs8PrivateKey() method, since that's the format you want your data in, and new .NET 5 PemEncoding class to simplify turning the DER encoded output into PEM+DER output. 如果您的出口商在 .NET 框架上,这是一个更复杂的问题 对于 .NET Standard 2.0,没有真正干净的解决方案(反映调用 .NET Core/.NET 5 的方法,否则使用 .NET 框架的 Windows 特定版本?)。

byte[] pkcs8PrivateKey;

using (RSA privateKey = x509Certificate.GetRSAPrivateKey())
{
    pkcs8PrivateKey = ExportPrivateKey(privateKey);
}

File.WriteAllText(
    "tls.cer",
    new string(PemEncoding.Write("CERTIFICATE", x509Certificate.RawData));

File.WriteAllText(
    "tls.key",
    new string(PemEncoding.Write("PRIVATE KEY", pkcs8PrivateKey));

...

private static byte[] ExportPrivateKey(RSA privateKey)
{
    try
    {
        // If it's plaintext exportable, just do the easy thing.
        return privateKey.ExportPkcs8PrivateKey();
    }
    catch (CryptographicException)
    {
    }

    using (RSA exportRewriter = RSA.Create())
    {
        // Only one KDF iteration is being used here since it's immediately being
        // imported again.  Use more if you're actually exporting encrypted keys.
        exportRewriter.ImportEncryptedPkcs8PrivateKey(
            "password",
            privateKey.ExportEncryptedPkcs8PrivateKey(
                "password",
                new PbeParameters(
                    PbeEncryptionAlgorithm.Aes128Cbc,
                    HashAlgorithmName.SHA256,
                    1)),
            out _);

        return exportRewriter.ExportPkcs8PrivateKey();
    }
}

暂无
暂无

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

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