Reputation: 101
I have an Azure App Service in which we have uploaded (via Key Vault) .pfx files to add them to Certificate Store. We have also added the configuration "WEBSITE_LOAD_CERTIFICATES" to access that certificate in Code. We are Successfully able to retrieve the certificate as X509Certificate2 object, but not able to export it back to a pfx file. It seems the Private key is not exportable, but we need to create the pfx file back, as we need to use that for our mSSL authentication with Apache Kafka. Any idea how to solve this? We followed steps in https://learn.microsoft.com/en-us/azure/app-service/configure-ssl-certificate-in-code#load-certificate-from-file. The error we get is, The error we are getting is "Key not valid for use in specified state."
Upvotes: 0
Views: 682
Reputation: 1063
As per the MSDoc, the private key of the certificate is not exportable when it is uploaded to the Azure App Service.
But, you can use the Azure Key Vault to export the certificate with the private key.
Load the certificate from the store
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);
X509Certificate2Collection certs = store.Certificates.Find(X509FindType.FindByThumbprint, CERTIFICATE_THUMB_PRINT, false);
if (certs.Count == 0)
{
}
else
{
certificate = certs[0];
}
store.Close();
Upload PFX to KeyVault
string pfxFile = @"C:\Tools\.pfx";
string certName = "certificateName";
string pfxPword = "secretvalue";
string keyVaultName = "keyVaultName";
Console.WriteLine("..PFX to KeyVault..");
var keyVaultUri = "https://" + keyVaultName + ".vault.azure.net";
var keyVaultClient = new KeyVaultClient(
new KeyVaultClient.AuthenticationCallback(FetchToken));
var pfx_Bytes = File.ReadAllBytes(pfxFile);
var base64EncodedCert = Convert.ToBase64String(pfx_Bytes);
var res = await keyVaultClient.ImportCertificateAsync(keyVaultUri,
certName,base64EncodedCert,pfxPword);
//Fetch Token
public static async Task<string> FetchToken(string authority,
string resrc,
string scope)
{
string clientId = "ClinetID";
string clientSecret = "ClientSecret";
var authContext = new AuthenticationContext(authority);
var result = await authContext.AcquireTokenAsync(resrc,
new ClientCredential(clientId, clientSecret));
if (result == null)
{
Console.WriteLine("Failed to fetch token...");
throw new ApplicationException("Failed to fetch token...");
}
return result.AccessToken;
}
For further information, refer to the SO link and Blog.
Upvotes: 1