Private/Get-ABMJWT.ps1
function Get-ABMJWT { [CmdletBinding( SupportsShouldProcess = $False, ConfirmImpact = "None", SupportsPaging = $False, PositionalBinding = $True) ] [OutputType([string])] param ( [Parameter(Mandatory = $true)] [String] $ClientId, [Parameter(Mandatory = $true)] [String] $KeyId, [Parameter(Mandatory = $true)] [ValidateScript({ Test-Path $_ })] [String] $KeyPath ) # Replace these with your actual Apple values: $client_id = $ClientId $team_id = $ClientId $key_id = $KeyId $audience = "https://account.apple.com/auth/oauth2/v2/token" $alg = "ES256" # Load the private key PEM content $privateKeyPem = Get-Content -Raw -Path $keyPath # Extract base64 key by removing PEM headers/footers and whitespace $base64Key = ($privateKeyPem -replace '-----.*-----', '') -replace '\s', '' $keyBytes = [Convert]::FromBase64String($base64Key) # Create ECDsa instance and import PKCS#8 private key $ecdsa = [System.Security.Cryptography.ECDsa]::Create() $bytesRead = 0 $ecdsa.ImportPkcs8PrivateKey($keyBytes, [ref]$bytesRead) # JWT Header (keep order consistent) $header = [ordered]@{ alg = $alg kid = $key_id typ = "JWT" } # JWT Payload with iat and exp (180 days max) $now = Get-Date $payload = [ordered]@{ sub = $client_id aud = $audience iat = Get-UnixTime $now exp = Get-UnixTime $now.AddDays(180) jti = [guid]::NewGuid().ToString() iss = $team_id } # Convert header and payload to JSON then base64url encode $headerJson = $header | ConvertTo-Json -Compress $payloadJson = $payload | ConvertTo-Json -Compress $encodedHeader = ConvertTo-Base64 ([System.Text.Encoding]::UTF8.GetBytes($headerJson)) $encodedPayload = ConvertTo-Base64 ([System.Text.Encoding]::UTF8.GetBytes($payloadJson)) # Create the message to sign $jwtData = "$encodedHeader.$encodedPayload" $jwtBytes = [System.Text.Encoding]::UTF8.GetBytes($jwtData) # Hash the message $sha256 = [System.Security.Cryptography.SHA256]::Create() $hash = $sha256.ComputeHash($jwtBytes) # Sign the hash returns raw r||s signature $rawSignature = $ecdsa.SignHash($hash) # Base64url encode the signature $encodedSignature = ConvertTo-Base64 $rawSignature # Combine to final JWT $jwt = "$jwtData.$encodedSignature" return $jwt } |