Is there any way to make uploaded certificate's private key exportable?

Charles He 1 Reputation point
2021-04-01T15:20:56.46+00:00

In Azure Cloud Service, I want to use below code to get client assertion, but the error at the line "var privateKeyXmlParams = certificate.PrivateKey.ToXmlString(true);" is "Key not valid for use in specified state.
".

X509Store store = new X509Store(StoreLocation.LocalMachine);  
store.Open(OpenFlags.ReadOnly);  
X509Certificate2Collection cers = store.Certificates.Find(X509FindType.FindBySubjectName, certificateName, false);  
if (cers.Count == 0)  
            throw new Exception("No certificate found.");  
  
X509Certificate2 certificate = cers[0];  
  
//Create RSACryptoServiceProvider  
var x509Key = new X509AsymmetricSecurityKey(certificate);  
var privateKeyXmlParams = certificate.PrivateKey.ToXmlString(true);  
var rsa = new RSACryptoServiceProvider();  
rsa.FromXmlString(privateKeyXmlParams);  
  
//alg represents the desired signing algorithm, which is SHA-256 in this case  
//kid represents the certificate thumbprint  
var header = new Dictionary<string, string>()  
{  
    { "alg", "RS256"},  
    { "kid", Encode(certificate.GetCertHash()) }  
};  
  
string token = Encode(Encoding.UTF8.GetBytes(JObject.FromObject(header).ToString())) + "." + Encode(Encoding.UTF8.GetBytes(JObject.FromObject(GetClaims(tenantId, clientId)).ToString()));  
  
string signature = Encode(rsa.SignData(Encoding.UTF8.GetBytes(token), new SHA256Cng()));  
string signedClientAssertion = string.Concat(token, ".", signature);  

I'm wondering if I can config the private key as exportable just as what I can do on my local machine. Can anyone help?

83669-kb-1-57x7kyj-markasexport.png

Azure Cloud Services
Azure Cloud Services
An Azure platform as a service offer that is used to deploy web and cloud applications.
705 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Amira Bedhiafi 27,446 Reputation points
    2024-11-19T23:10:04.8433333+00:00

    To make the private key exportable in Azure Cloud Services or any Windows-based platform, you need to configure the certificate correctly during its import. Certificates with non-exportable private keys are typically imported with that restriction due to security considerations. However, you can address this in a few ways:

    1. Use an Exportable Key When Importing the Certificate

    When importing a certificate into Azure or your local machine, you can specify that the private key should be exportable:

    • Use the certutil command-line tool:
      
        certutil -importpfx MyCertificate.pfx AT_KEYEXCHANGE
      
      
      Add the -privatekey:exportable flag to ensure the private key is exportable:
      
        certutil -importpfx MyCertificate.pfx AT_KEYEXCHANGE -privatekey:exportable
      
      
    • Programmatically via PowerShell:
      
        $password = ConvertTo-SecureString -String "YourPassword" -Force -AsPlainText
      
        Import-PfxCertificate -FilePath "C:\Path\To\Certificate.pfx" -CertStoreLocation Cert:\LocalMachine\My -Password $password -Exportable
      
      

    2. Export and Re-Import the Certificate with an Exportable Key

    If you have the original certificate .pfx file:

    1. Export it from its original location as an exportable .pfx.
    2. Re-import it with the Exportable flag enabled.

    3. Check Key Permissions

    If the private key isn't explicitly set to be non-exportable, the error might also arise from insufficient permissions. Grant the appropriate user account permissions to access the private key:

    1. Open certlm.msc (Local Computer Certificates Store).
    2. Find your certificate under Personal > Certificates.
    3. Right-click the certificate and choose All Tasks > Manage Private Keys.
    4. Add the user account running your application with appropriate permissions (Read and Full Control).

    4. Generate the Certificate Programmatically with Exportable Key

    If you are generating the certificate programmatically in Azure or locally, ensure you create it with the private key exportable:

    • Using PowerShell:
      
        New-SelfSignedCertificate -DnsName "YourDomain" -CertStoreLocation "Cert:\LocalMachine\My" -KeyExportPolicy Exportable
      
      

    5. Use Key Vault for Certificate Management

    Azure Key Vault provides secure storage for certificates and allows you to access the private key when needed:

    1. Import the certificate into Azure Key Vault, ensuring the private key is included.
    2. Access the private key using the Azure Key Vault SDK or API.

    Example in C#:

    
    var keyClient = new KeyClient(new Uri(keyVaultUrl), new DefaultAzureCredential());
    
    var key = await keyClient.GetKeyAsync(certificateName);
    
    var rsa = key.ToRSA();
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.