The Azure Key Vault ECC Certificate FAQ

The Error

A common request from you, our valued Microsoft customer, is that Key Vault support Elliptical Curve Cryptography (ECC) Certificates which are useful in payment schemes such as Apple Pay.  ECC was not a supported format for Key Vault for a long time, and even now, there is no option to create an ECC certificate in the portal.  But you need a self-signed ECC certificate for Apple Pay, so you think "Let's just use OpenSSL!"

The first relevant hit that is returned on Bing when searching on "Create a Self Signed ECC Certificate" is this one.  The instructions are clear and easy to follow and use OpenSSL, exactly as you wanted.  So you create your ECC Certificate and happily go into the portal. Unfortunately, when uploading the certificate, you see this error message:

And now you're confused.  You can clearly see that your Access Policy includes import:

To you, there's clearly a bug.  So you call Azure Support and get a hold of one of our awesome engineers.  Like a good engineer who's trying to get you up and running, she says "Let's try Powershell instead and see what happens."  Of course you do and now you see this:

"Elliptic Curve Cryptography Public Key Algorithm of the X509 certificate in the certificate chain is not supported."  

Well gosh - that's kind of a showstopper. It's pretty clear what it says. But it's not true, and you know it because you found this documentation right on the Microsoft website for Key Vault and the CreateCertificate REST API:

So now you need to open a support ticket with Microsoft in order to straighten this out.  You're not the first person to do this and I know this because I asked the Key Vault product team and got the correct instructions on how to make it work.  So here is the information that I got from a smart SDE, Kashif Mehmood:


  • Do we support ECC Certificates?
  • What ECC Curves do we support?
    Documented here [NIST P-256, NIST P-384, NIST P-521, SECG SECP256K1]
    Note: There is a bug preventing SECP256K1 curve type. We are working on this. 
  • What’s the minimum REST API version with which ECC is supported?
  • Do we have .NET SDK support?
    Yes – documented here 
  • Do have support in Azure Portal, Azure CLI, Azure PowerShell? 
    Azure Portal – Not at this time
    Azure PowerShell – Not at this time
    Azure CLI – Yes 
  • I created an ECC PFX with Open SSL. But it does not work why?
    By default, Open SSL certs do not have:
    1. PFX created have keys stating both signature and key exchange while key vault expects signature
    2. Key Usage on the certs

    In order to create the certificate using OpenSSL, please use the commands below with the attached config file to generate the PFX. Supported values of curves for OpenSSL commands are:  prime256v1, secp384r1, secp521r1, secp256k1 
  • What about PEM with Open SSL?
    We are investigating this as of the time of this post.

  • What version of Azure CLI does this work with?
    azure-cli                         2.0.65

  • What is the command in CLI to import an ECC Certificate?
    Here's an example:
    C:\Users\KashifM>az keyvault certificate import --vault-name KM-KV-WU-WU --file "C:\Users\KashifM\Downloads\Certs\OpenSSL\Customer\" --password "Removed" --name OpenSslPrime256v105231249
      "attributes": {
        "created": "2019-05-23T19:52:08+00:00",
        "enabled": true,
        "expires": "2020-05-22T19:17:06+00:00",
        "notBefore": "2019-05-23T19:17:06+00:00",
        "recoveryLevel": "Recoverable+Purgeable",
        "updated": "2019-05-23T19:52:08+00:00"

Specific commands needed to create an ECC Certificate using OpenSSL

openssl ecparam -name prime256v1 -out
openssl ecparam -in -text -noout

openssl req -config keyUsage.conf -new -x509 -sha256 -newkey -nodes -keyout -days 365 -out
openssl x509 -in -text -noout

openssl pkcs12 -export -keysig -out -inkey -in

Example of Creating an ECC Certificate using OpenSSL

C:\Users\KashifM\Downloads\Certs\OpenSSL\Customer>openssl ecparam -name prime256v1 -out

C:\Users\KashifM\Downloads\Certs\OpenSSL\Customer>openssl ecparam -in -text -noout
ASN1 OID: prime256v1

C:\Users\KashifM\Downloads\Certs\OpenSSL\Customer>openssl req -config keyUsage.conf -new -x509 -sha256 -newkey -nodes -keyout -days 365 -out
Generating an EC private key
writing new private key to ''
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
Country Name (2 letter code) [US]:US
State or Province Name (full name) [WA]:WA
Locality Name (eg, city) [Redmond]:Redmond
Organization Name (eg, company) [MSFT]:MSFT
Common Name (e.g. server FQDN or YOUR name) []
Email Address []

C:\Users\KashifM\Downloads\Certs\OpenSSL\Customer>openssl x509 -in -text -noout
        Version: 3 (0x2)
        Serial Number:
    Signature Algorithm: ecdsa-with-SHA256
        Issuer: C = US, ST = WA, L = Redmond, O = MSFT, CN =, emailAddress =
            Not Before: May 23 19:17:06 2019 GMT
            Not After : May 22 19:17:06 2020 GMT
        Subject: C = US, ST = WA, L = Redmond, O = MSFT, CN =, emailAddress =
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Subject Key Identifier:
            X509v3 Authority Key Identifier:

            X509v3 Basic Constraints:
            X509v3 Key Usage:
                Digital Signature
            Netscape Comment:
                OpenSSL Generated Certificate
    Signature Algorithm: ecdsa-with-SHA256

C:\Users\KashifM\Downloads\Certs\OpenSSL\Customer>openssl pkcs12 -export -keysig -out -inkey -in
Enter Export Password:
Verifying - Enter Export Password:

Volume in drive C has no label.
Volume Serial Number is 74A4-87BA

Directory of C:\Users\KashifM\Downloads\Certs\OpenSSL\Customer

05/23/2019  12:43 PM    <DIR>          .
05/23/2019  12:43 PM    <DIR>          ..
05/23/2019  12:17 PM             1,006
05/23/2019  12:43 PM             1,224
05/23/2019  12:16 PM               246
05/23/2019  12:16 PM                78
05/23/2019  12:10 PM             1,502 keyUsage.conf
               5 File(s)          4,056 bytes
               2 Dir(s)  22,093,053,952 bytes free

Contents of the file "keyUsage.conf"

[ req ]
distinguished_name  = subject
req_extensions      = req_ext
x509_extensions     = x509_ext
string_mask         = utf8only

[ subject ]
countryName                 = Country Name (2 letter code)
countryName_default         = US
stateOrProvinceName         = State or Province Name (full name)
stateOrProvinceName_default = WA
localityName                = Locality Name (eg, city)
localityName_default        = Redmond
organizationName            = Organization Name (eg, company)
organizationName_default    = MSFT
commonName                  = Common Name (e.g. server FQDN or YOUR name)
commonName_default          =
emailAddress                = Email Address
emailAddress_default        =

# Section x509_ext is used when generating a self-signed certificate. I.e., openssl req -x509 ...
[ x509_ext ]
subjectKeyIdentifier    = hash
authorityKeyIdentifier  = keyid,issuer
basicConstraints        = CA:FALSE
# One/All of the below values are required
# DigitalSignature, CrlSign, KeyCertSign, NonRepudiation
keyUsage                = digitalSignature
nsComment               = "OpenSSL Generated Certificate"

[ req_ext ]
subjectKeyIdentifier    = hash
basicConstraints        = CA:FALSE
# One/All of the below values are required
# DigitalSignature, CrlSign, KeyCertSign, NonRepudiation
keyUsage                = digitalSignature
nsComment               = "OpenSSL Generated Certificate"

I hope the above helps.  Please reach out to @AzIdentity on Twitter for questions or comments.


This blog will have a slight change in scope

This blog was originally intended to be a place for my previous support team (the Azure Identity Incubation Team) to post content related to the various technologies that we worked on.  It turned out to be a place where I have been posting about Azure Key Vault for the past year.  To reflect this, I am changing the focus of this blog to be exclusively Key Vault.  I will be leaving the existing non-Key Vault posts in place until a better location is found for them.  Thank you.


Getting It Right: Key Vault Access Policies


Azure customers of all sizes are using ARM templates, Powershell, and CLI in order to create Registered Applications/Service Principals and then assign them to an Access Policy in the Key Vault in order to perform operations.  In performing these assignments, it is frequent that customers call into Key Vault support trying to understand why their Service Principal is receiving an HTTP 403 (Forbidden) when attempting to access the Key Vault data plane.  I want to clear up what's going on with this so that you have a better understanding and can avoid this problem.

Key Vault Access Policy In the Portal

Let's review a Registered Application that I've newly created using the portal.  We can clearly see all of the GUIDs associated with this Registered Application which are important to creating the Access Policy.

So now I create an Access Policy for this Registered Application in my Key Vault:


Next, let's get an access token using the Application ID (Client Id) and Client Secret (Key) that I created in the Application Registration blade in AAD:


Accept: application/json
Content-Type: application/x-www-form-urlencoded
Content-Length: 168
Expect: 100-continue<removed>&grant_type=client_credentials


Response (some info removed)

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Fri, 17 May 2019 14:29:02 GMT
Content-Length: 1324


Now that I've got the token, I can make a successful request to Key Vault for a secret:


x-ms-client-request-id: 7b431436-fb67-4f44-b7c3-b91822f5d0aa
accept-language: en-US
Authorization: Bearer <removed>
User-Agent: FxVersion/4.7.3324.0 OSName/Windows10Enterprise OSVersion/6.3.17763 Microsoft.Azure.KeyVault.KeyVaultClient/

Response (some info removed)

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Expires: -1
Date: Fri, 17 May 2019 14:55:24 GMT
Content-Length: 223


You may be looking at this and wondering why I am walking you through a standard setup and request/response.  It's because I want to show you that this works as expected, even though the next step is the confusing part - the values that are kept in the Key Vault for an access policy. 

Key Vault Properties

Now look at the Key Vault using Powershell:

And more specifically, check out the Access Policy for the AKVAccessPolicyServicePrincipal:

There are three important things to note here:

  • There is no Application Id listed as a property of this Access Policy
  • The ObjectID listed here (92ba...) does not match the ObjectId (7da4...) shown in the registered application (see above)
  • The Application Id (70a3...) of the registered application from above is shown in the Display Name section

At this point you should be wondering what is going on with this, so let's figure out where the ObjectID 92ba... came from.

Enterprise Applications

Go back into the Azure portal, AAD Service, then into the "Enterprise Registrations" (have you ever even looked here before?):



Now we see that this Enterprise Application - with the same name and Application Id as my registered application - but a different ObjectID - is what we've registered in the Key Vault Access Policy!  But what in the world is an Enterprise Application?

Here are a couple of important definitions from official documentation:

  • Application objects - Although there are exceptions, application objects can be considered the definition of an application.
  • Service principals - Can be considered an instance of an application. Service principals generally reference an application object, and one application object can be referenced by multiple service principals across directories.

One additional really important piece of information from the above link:
You can manage service principals in the Azure portal through the Enterprise Applications experience. 

Now we understand - a Service Principal is NOT the same as a Registered Application and for Key Vault, we do not give an access policy to a Registered Application but to a Service Principal related to the Registered Application.  


Key Vault Access Policy via Powershell

Let's get back to Powershell and properly creating Access Policies.  I am going to delete the above Access Policy and attempt to recreate it using Powershell. There are three ways of creating an Access Policy:

  1. Set-AzureRmKeyVaultAccessPolicy [-VaultName] <String> [-ApplicationId <Guid>] -ObjectId <String> -PermissionsToKeys all
  2. Set-AzureRmKeyVaultAccessPolicy [-VaultName] <String> -PermissionsToKeys all -ServicePrincipalName <String>
  3. Set-AzureRmKeyVaultAccessPolicy [-VaultName] <String> -PermissionsToKeys all -UserPrincipalName <String>

For most people with an Application Id and Object Id, #1 might seem to do the trick, so let's see what happens when we use this.  Let's also have a reminder of what it looks like when properly created in the portal:

Upon running this cmdlet, we are immediately met with a request for an ObjectId.  I can put in the ObjectId of the Registered Application and it seems fine until I try to use it (I won't show that).  Let's see what that looks like in the Key Vault:

So that really might look ok to most people, but as you noticed above, that's not what we really want.  The Object Id is not correct (we know that now), and the correct working Access Policy does not have an Application Id but this one does.  I reminded you what a properly registered Access Policies looks like, so let's look at the one we just created:

You can see that the name is correct, but the icon and coloring is different.  This should be a clue that something is wrong.  Let's look at doing this correctly in one of two ways:

  1. Use the Object ID of the Enterprise App.  This is identical to the Access Policy we created earlier in the portal, and the icon looks correct:

  2. Use the Application Id of the Registered Application as the Service Principal name. This automatically extracts the Enterprise Application Object ID and places it into Object ID of the Key Vault properties, and also populates the Display Name - exactly like above.


Application Id

At this point you are probably asking what an Application Id is for in an Access Policy.  Go back to the portal and into the new Access Policy blade.  Notice the "Authorized Application" part at the bottom of this image:

The Application Id property of a Key Vault refers directly to that "Authorized Application" part of an Access Policy. This is for On-Behalf-Of Authorization scenarios which means that authorization is granted to a specific user only via a specific application. Without other Access Policies, the user cannot access the Key Vault without the app, and the app cannot access the Key Vault without the user.  Most organizations will not use this feature, but I know that some have. 


It's important to know exactly the correct Object ID to use in an Access Policy.  The difference between a registered application and an Enterprise App/Service Principal seems to be the #1 most confusing part of this.  However, I hope this blog post clears up the issues around this and makes your life easier when troubleshooting your Access Policy issues.

Finally: I want to thank Scott Cottrille, Principal Group Software Engineering Manager of Azure Key Vault for the inspiration for this post.

I hope this helps you out when using the Azure Key Vault!  Please follow us on Twitter and retweet!
@WinDevMatt @AzIdentity


Maximum Number of Objects in a Key Vault

This one is short and sweet:  people want to know the maximum number of objects in an Azure Key Vault.  Per the Azure Key Vault product team:

  • There is no limit on number of keys, secrets, or certificates in a Key Vault.
  • There is no maximum number of versions of secrets, keys or certificates.
  • The maximum number of access policies in a Key Vault as of March 2019 is 1024.

I hope this helps.

Key Vault Firewall access by Azure App Services

More than a few support cases are created when Key Vault users wisely decide to enable the Firewall settings on their vault.  Then the problem begins:  Azure App Service websites are no longer able to access the Key Vault, and end up creating an error message like the following:

Operation returned an invalid status code 'Forbidden'

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: Microsoft.Azure.KeyVault.Models.KeyVaultErrorException: Operation returned an invalid status code 'Forbidden'

Forbidden is means that the HTTP response code is 403.  In the past, 403 has always meant:

  1. The identity was confirmed
  2. The resource is correct
  3. Either the lack of an access policy OR an access policy itself prevents the resource from being obtained by the confirmed identity

However, since the Azure Key Vault Firewall And Virtual Networks feature was released, it can also mean that the client is not allowed by virtue of the calling location. Here's a look at that part of Key Vault:

If the Key Vault Firewall/VNet is activated, there are exactly three ways to get into the Key Vault (given that an access policy is also in place):

  1. Be on the same Virtual Network as the Key Vault
  2. Be on the Firewall IP address whitelist
  3. Be a "Trusted Microsoft Service"

I think that the first two are self-explanatory.  However, #3 is causing a headache for many customers.

This is the explicit list of "Trusted Microsoft Services" (as of the time of this authoring):

Trusted services

Here's a list of trusted services that are allowed to access a key vault if the Allow trusted services option is enabled.

Trusted service Usage scenarios
Azure Virtual Machines deployment service Deploy certificates to VMs from customer-managed Key Vault.
Azure Resource Manager template deployment service Pass secure values during deployment.
Azure Disk Encryption volume encryption service Allow access to BitLocker Key (Windows VM) or DM Passphrase (Linux VM), and Key Encryption Key, during virtual machine deployment. This enables Azure Disk Encryption.
Azure Backup Allow backup and restore of relevant keys and secrets during Azure Virtual Machines backup, by using Azure Backup.
Exchange Online & SharePoint Online Allow access to customer key for Azure Storage Service Encryption with Customer Key.
Azure Information Protection Allow access to tenant key for Azure Information Protection.
Azure App Service Deploy Azure Web App Certificate through Key Vault.
Azure SQL Database Transparent Data Encryption with Bring Your Own Key support for Azure SQL Database and Data Warehouse.
Azure Storage Storage Service Encryption using customer-managed keys in Azure Key Vault.
Azure Data Lake Store Encryption of data in Azure Data Lake Store with a customer-managed key.


You will look at the list and find "Azure App Services".  However, it's the next column which is just as important:  the only scenario where an App Service is trusted is for deployment of App Service Certificates.

That's all. That's it.


To show this, I enabled the firewall with the trusted Microsoft Services, as well as Audit logging in my Azure Key Vault and attempted to access it from my Azure App Service.  I get this message in my website:

Looking in my audit logs, I find the following:

    "time": "2019-01-03T19:14:18.2665709Z",
    "category": "AuditEvent",
    "operationName": "SecretGet",
    "resultType": "Success",
    "resultDescription": "Client address ( is not authorized and caller is not a trusted service",
    "correlationId": "c8e4f5ef-6def-411d-9a24-ab43f00d0566",
    "callerIpAddress": "",

As soon as I added the IP address of my web site...