Azure 从 byte[] 加载 X509Certificate2 找不到指定的文件

问题描述 投票:0回答:1

我有一个 Azure Function App,我试图从中提取 Azure Key Vault 的证书。我的代码如下:

    private X509Certificate2 GetCertificate(
        CertificateClient certificateClient,
        SecretClient secretClient,
        string certificateName)
    {
        KeyVaultCertificateWithPolicy certificate = certificateClient.GetCertificate(certificateName);

        // Return a certificate with only the public key if the private key is not exportable.
        if (certificate.Policy?.Exportable != true)
        {
            return new X509Certificate2(certificate.Cer);
        }

        // Parse the secret ID and version to retrieve the private key.
        string[] segments = certificate.SecretId.AbsolutePath.Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries);
        if (segments.Length != 3)
        {
            throw new InvalidOperationException($"Number of segments is incorrect: {segments.Length}, URI: {certificate.SecretId}");
        }

        string secretName = segments[1];
        string secretVersion = segments[2];

        KeyVaultSecret secret = secretClient.GetSecret(secretName, secretVersion);
        
        if ("application/x-pkcs12".Equals(secret.Properties.ContentType, StringComparison.InvariantCultureIgnoreCase))
        {
            byte[] pfx = Convert.FromBase64String(secret.Value);

            // Exception thrown here
            return new X509Certificate2(pfx);
        }

        throw new NotSupportedException($"Only PKCS#12 is supported. Found Content-Type: {secret.Properties.ContentType}");
    }
}

我已将 Key Vault 中的访问权限设置为

all
并向该功能添加了额外的日志记录。我可以看到它运行到我评论过的行,并且
pfx
的内容与我添加到 Key Vault 的证书完全匹配。

当尝试创建

X509Certificate2
的实例时,我收到异常
The system cannot find the file specified.
,但没有有关它引用的文件的信息。

奇怪的是,如果使用我的个人 Azure 凭据在本地运行,我会得到完全相同的字节数组,并且不会出现该异常。

azure azure-functions azure-keyvault x509certificate2
1个回答
0
投票

系统找不到指定的文件。

要解决此错误,请在

WEBSITE_LOAD_USER_PROFILE=1
中添加应用程序设置
Function App=>Settings=>Configuration/Environment Variables
。请参阅GitHub问题。

将 Key Vault 引用设置为 Function App 中设置的值。

@Microsoft.KeyVault(SecretUri=https://<keyvaultname>.vault.azure.net/certificates/<your_Certificate_name>/)

我的函数应用程序的应用程序设置:

enter image description here

  • 创建 Azure Key Vault 并向服务主体提供所需的权限。

enter image description here

  • 我已创建 X509 证书并导入到 Azure Key Vault 中。
  • 能够使用以下代码从 Azure Key Vault 检索证书。

代码片段:

[FunctionName("Function1")]
public static async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
    ILogger log)
{
    string keyVaultUrl = "https://<keyvault>.vault.azure.net/";
    string certificateName = "kpcert";
    X509Certificate2 certificate ;

    var certificateClient = new CertificateClient(new Uri(keyVaultUrl), new DefaultAzureCredential());
    var secretClient = new SecretClient(new Uri(keyVaultUrl), new DefaultAzureCredential());

     certificate = await GetCertificate(certificateClient, secretClient, certificateName);

    log.LogInformation("Certificate retrieved successfully.");

    return new OkObjectResult(certificate);
}

private static async Task<X509Certificate2> GetCertificate(
    CertificateClient certificateClient,
    SecretClient secretClient,
    string certificateName)
{
    KeyVaultCertificateWithPolicy certificate = await certificateClient.GetCertificateAsync(certificateName);

    if (certificate.Policy?.Exportable != true)
    {
        return new X509Certificate2(certificate.Cer);
    }

    string[] segments = certificate.SecretId.AbsolutePath.Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries);
    if (segments.Length != 3)
    {
        throw new InvalidOperationException($"Number of segments is incorrect: {segments.Length}, URI: {certificate.SecretId}");
    }

    string secretName = segments[1];
    string secretVersion = segments[2];

    KeyVaultSecret secret = await secretClient.GetSecretAsync(secretName, secretVersion);

    if ("application/x-pkcs12".Equals(secret.Properties.ContentType, StringComparison.InvariantCultureIgnoreCase))
    {
        byte[] pfx = Convert.FromBase64String(secret.Value);
        return new X509Certificate2(pfx);
    }

    throw new NotSupportedException($"Only PKCS#12 is supported. Found Content-Type: {secret.Properties.ContentType}");
}

控制台输出:

enter image description here

本地响应:

enter image description here

传送门: enter image description here

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.