Convert RSA XML Private Key to PEM Format with PowerShell

Recently I was working with a particular application that used certificates to secure communication. I wanted to put the certificates into Azure KeyVault. Azure KeyVault naturally allows you to store certificates. However, it only lets you upload certificates that are in PFX (PKCS#12) or CER (DER or BASE64 encoded). I needed to convert my RSA XML Private Key to PEM Format (DER encoded in Base64). Naturally using PowerShell. The script snippet I created to do this is in this post as I know I’ll need it again in the future.

Overview

The RSA XML format for storing private keys is a specific serialization format where the RSA cryptographic key details are stored as XML. This format is widely used in Microsoft environments and is particularly convenient for interoperability within .NET applications.

RSA Private Key in XML Format example

<RSAKeyValue>
<Modulus>oNsp...b9M=</Modulus>
<Exponent>AQAB</Exponent>
<P>6Bq...1M=</P>
<Q>x4R...Ak=</Q>
<DP>VjL...QI=</DP>
<DQ>Vx5...BI=</DQ>
<InverseQ>C4t...3g=</InverseQ>
<D>HIk...0M=</D>
</RSAKeyValue>

PEM Format example

-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCk9C3ciPLVubsD
92oRPARUs/o90rCgQ7/9HCr6sVVROrCxEk9rNx4wK2byCBubG4gZFg66p2elCg7w
eI5aGyxgJHqcQ268R1sSud59AtvF1xi6iUNNU5U2ea6Y7bTHoOUijYx28aTr6VMM
....
8PTz6covjoOJqxQJOvM7nM0CsJawG9ccw3YXyd9KgRIdSt6ooEhb7N8W2EXYoKl3
g1i2t41Q/SC3HUGC5mJjpO8=
-----END PRIVATE KEY-----

Certificate Conversion Script

Here is my small script to convert RSA XML Private Key to PEM Format with PowerShell. It takes in the private key from a file in the local directory named private.key converts it to PEM format and outputs it to private_key.pem in the local directory.

# Example RSAKeyValue XML format
$xmlPrivateKey = Get-Content .\private.key

# Load the XML string into an XmlDocument
$xml = New-Object System.Xml.XmlDocument
$xml.LoadXml($xmlPrivateKey)

# Function to properly format and convert Base64
function Convert-ToBase64Pem {
param (
$data,
$type
)
$base64 = [Convert]::ToBase64String($data)
$output = "-----BEGIN $type-----`n"
for ($i = 0; $i -lt $base64.Length; $i += 64) {
$output += ($base64.Substring($i, [Math]::Min(64, $base64.Length - $i)) + "`n")
}
$output += "-----END $type-----"
return $output
}

# Create the RSA parameters object
$rsaParams = New-Object System.Security.Cryptography.RSAParameters
$rsaParams.Modulus = [Convert]::FromBase64String($xml.RSAKeyValue.Modulus)
$rsaParams.Exponent = [Convert]::FromBase64String($xml.RSAKeyValue.Exponent)
$rsaParams.D = [Convert]::FromBase64String($xml.RSAKeyValue.D)
$rsaParams.P = [Convert]::FromBase64String($xml.RSAKeyValue.P)
$rsaParams.Q = [Convert]::FromBase64String($xml.RSAKeyValue.Q)
$rsaParams.DP = [Convert]::FromBase64String($xml.RSAKeyValue.DP)
$rsaParams.DQ = [Convert]::FromBase64String($xml.RSAKeyValue.DQ)
$rsaParams.InverseQ = [Convert]::FromBase64String($xml.RSAKeyValue.InverseQ)

# Create an RSA object and import the parameters
$rsa = New-Object System.Security.Cryptography.RSACryptoServiceProvider
$rsa.ImportParameters($rsaParams)

# Export the RSA parameters to PEM-format private key
$rsaPrivateParams = $rsa.ExportParameters([System.Security.Cryptography.RSAParameters]::$true)
$rsaPrivateBlob = $rsa.ExportRSAPrivateKey()
$privateKeyPem = Convert-ToBase64Pem $rsaPrivateBlob "RSA PRIVATE KEY"

# Save to PEM file
$privateKeyPem | Out-File -FilePath ".\private_key.pem"

Summary

For some reason I didn’t find examples on how to do this and needed to figure it out. As always documenting it here for future me and anyone else with a similar need.

Darren Robinson

Bespoke learnings from a Microsoft Identity and Access Management Architect using lots of Microsoft Identity Manager, Azure Active Directory, PowerShell, SailPoint IdentityNow and Lithnet products and services.

Recent Posts

EntraPulse – Your AI-Powered Gateway to Microsoft Graph & Docs

Today, I’m super excited to finally announce the Beta release of EntraPulse Lite – a…

2 months ago

Lokka MCP Authentication Enhancements

I'm excited to share some significant authentication enhancements I've contributed to the Lokka MCP Server…

3 months ago

AI Inception: Building AI Solutions with AI for AI

Last month I had the pleasure of speaking at the Sydney event for Global Azure.…

3 months ago

A Have I Been Pwned MCP Server for Claude

Model Context Protocol (MCP) is a powerful framework that extends AI clients like Claude and…

5 months ago

Azure AI Developer Hackathon

I've just completed participating in the Azure AI Developer Hackathon that was looking to provide…

5 months ago

Dynamics 365 CE (Sales, CRM) IAM PowerShell Module

Updated: July 2025 v1.0.2 Fixes issue setting D365SalesGlobals enabling session management for D365 Sales API…

6 months ago

This website uses cookies.