Azure AD client certificate rollover


This Azure AD sample shows how to use OAuth2 Client Credential flow with an X509 certificate for authentication. Here is a procedure I use to periodically rollover the certificates.

In order to maintain continuous ability to authenticate a client you will want to define at least two certificates so that as you replace one, the other one is still available for authentication. That way you can modify the list of certificates in Azure AD and at a later stage modify the application to use the latest certificate as credential.

[Updated: 10/14/2016]. There is in fact a much simple process to do this without mucking around with the manifest. The following PowerShell script will create and upload a new certificate to AAD. You can use Get-MsolServicePrincipalCredential to list existing credentials and Remove-MsolServicePrincipalCredential to remove expired credentials. Note that this process will create a credential for a service principal, not the application itself, which means it will work whether the application is access from the tenant which owns it or from another tenant (in case it is a multi-tenant app):

# Input params
$principalName = "https://o365withX509.com/"
$cName = "CN=o365auth7"
$CertStart = "05/01/2016"
$CertEnd = "05/01/2017"
$cerFile = $Home + "\o365id2.cer"

#login to AAD tenant
$creds = get-credential
connect-msolservice -Credential $creds

#Create cert
$env:Path = $env:Path + ";C:\Program Files (x86)\Windows Kits\10\bin\x64"
makecert.exe -r -pe -n $cName -sr LocalMachine -ss My -len 2048 -e $CertEnd $cerFile

$cer = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$cer.Import($cerFile)
$binCert = $cer.GetRawCertData()
$base64Value = [System.Convert]::ToBase64String($binCert);

New-MsolServicePrincipalCredential -ServicePrincipalName $principalName -Value $base64Value -Type Asymmetric
Get-MsolServicePrincipalCredential -ServicePrincipalName $principalName -ReturnKeyValues $false
echo $cer.Thumbprint

[0/14/2016: remainder left for sentimental reasons]

Assuming you have already uploaded a manifest file as per sample, here is my rollover process.

  1. Some time before the original certificate expires download the current application manifest. It will include the originally uploaded certificate data as follows (mine already has two certificates as I have already run this process several times). Note that the value of the certificate is null.
"keyCredentials": [{

"customKeyIdentifier": "rOAQ2Aj8VGKpoIo5i13C3CUHI24=",

"endDate": "2017-12-31T07:00:00Z",

"keyId": "699f8258-35a0-425e-994b-7c2fb40907c6",

"startDate": "2016-05-05T12:35:15Z",

"type": "AsymmetricX509Cert",

"usage": "Verify",

"value": null

},

{

"customKeyIdentifier": "/QzO73uscNVyUA6UmR8xnbYu3Yg=",

"endDate": "2016-12-31T07:00:00Z",

"keyId": "80bcca76-d40b-462a-bb98-4990b6b505b4",

"startDate": "2016-05-05T12:26:02Z",

"type": "AsymmetricX509Cert",

"usage": "Verify",

"value": null

}

],

  1. Remove the expiring certificate (seems like it is always the last one in the list above). Obviously, do not remove any un-expired certificates you want to keep.
  2. Generate a new certificate and manifest snippet (see PowerShell script below).
  3. Run the PowerShell script (see below) to generate manifest fragment with data for the new key.
  4. Add this fragment to your keyCredentials in the downloaded manifest. Here is an example of the modified fragment. I have removed the oldest key from the original list and added the new one:
"keyCredentials": [{

"customKeyIdentifier": "/QzO73uscNVyUA6UmR8xnbYu3Yg=",

"endDate": "2016-12-31T07:00:00Z",

"keyId": "80bcca76-d40b-462a-bb98-4990b6b505b4",

"startDate": "2016-05-05T12:26:02Z",

"type": "AsymmetricX509Cert",

"usage": "Verify",

"value": null

},

{

"customKeyIdentifier":"rOAQ2Aj8VGKpoIo5i13C3CUHI24=",

"keyId": "699f8258-35a0-425e-994b-7c2fb40907c6",

"value":"MIIDGjCCAgagAwIBAgIQ1+…..",

"type": "AsymmetricX509Cert",

"usage": "Verify"

}

],

  1. Upload the new manifest.
  2. Your application should still be able to authenticate with the older certificate (expiring 12/31/2016 in the manifest above). You should now deploy the new certificate so that it becomes available to your client to use it instead. (Note that this process assumes your client, as per sample uses the Distinguished Name to find the certificate with the furthest expiry date).

Here is the PowerShell script to generate the manifest fragment with a new key. You need to replace the start and expiry dates and cer file name values (I am not a PS expert as this code shows). The script assumes you have Windows SDK installed as per path below.

# Input params$CertStart = "05/01/2016"

$CertEnd   = "08/01/2016"

$cerFile = "TodoListDaemonWithCert.cer"

 

#Add the makecert path to the active path variable

$env:Path = $env:Path + ";C:\Program Files (x86)\Windows Kits\8.1\bin\x64"

makecert.exe -r -pe -n "CN=TodoListDaemonWithCert" -ss My -len 2048 -e $CertEnd $cerFile

 

# Change output line length to accomodate cert public key encoded value

$rawUI = $Host.UI.RawUI

$oldSize = $rawUI.BufferSize

$typeName = $oldSize.GetType( ).FullName

$newSize = New-Object $typeName (2000, $oldSize.Height)

$rawUI.BufferSize = $newSize

 

# calc manifest values

$cer = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2

$cer.Import($cerFile)

$bin = $cer.GetRawCertData()

$base64Value = [System.Convert]::ToBase64String($bin)

$bin = $cer.GetCertHash()

$base64Thumbprint = [System.Convert]::ToBase64String($bin)

$keyid = [System.Guid]::NewGuid().ToString()

 

 

# output string to paste into rollover manifest

"{"

"""customKeyIdentifier"":""" + $base64Thumbprint + ""","

"""keyId"": """ + $keyid + ""","

"""value"":""" + $base64Value + ""","

"""type"": ""AsymmetricX509Cert"","

"""usage"":" + """Verify"""

"}"

 

 

 


Comments (0)

Skip to main content