I have an Azure Function App from which I'm trying to pull a certificate from Azure Key Vault. My code is as follows:
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}");
}
}
I've set the access permission in Key Vault to all and added additional logging to the function. I can see that it runs to the line that I've commented, and it the content of pfx exactly matches the certificate which I added to Key Vault.
When trying to create an instance of X509Certificate2 I get the exception The system cannot find the file specified. with no information about what file it's referencing.
The strange part is that if run locally with my personal Azure credentials, I get the exact same byte array back and I don't get that exception.
To resolve this error, add the application setting
WEBSITE_LOAD_USER_PROFILE=1in theFunction App=>Settings=>Configuration/Environment Variables. Refer GitHub article.Set the key vault reference as the value of the setting in the Function App.
Application Settings of my function app:
Code Snippet:
Console output:
Local Response:
Portal: