Functions/Test-JWT.ps1
function Test-JWT { [CmdletBinding()] [OutputType([string])] param ( [Parameter( Mandatory, ParameterSetName='HMAC', HelpMessage='Enter the JWT.' )] [Parameter( Mandatory, ParameterSetName='RSA', HelpMessage='Enter the JWT.' )] [ValidatePattern('(^[\w-]*\.[\w-]*\.[\w-]*$)')] [string]$JWT, [Parameter( Mandatory, ParameterSetName='RSA', HelpMessage='Enter the path of the public key' )] [System.IO.FileInfo]$PublicKey, [Parameter( Mandatory, ParameterSetName='HMAC', HelpMessage='Enter the HMAC secret' )] [string]$Secret ) begin { } process { try { #region Reversing and splitting the JWT $header, $payload, $signature = $JWT.Split(".") $preparedSignature = $signature.Insert(($signature.Length), "==").Replace('-', '+').Replace('_', '/') $bytes = [System.Convert]::FromBase64String($preparedSignature) $headerDecoded = [System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($header)) | ConvertFrom-Json #endregion Set-Content -Path $env:TEMP\data.txt -Value "$header.$payload" -NoNewline Set-Content -Path $env:TEMP\sig.txt -Value $bytes -AsByteStream #region Verify signature switch ($headerDecoded.alg) { 'RS256' { $result = openssl dgst -sha256 -verify $PublicKey -signature $env:TEMP\sig.txt $env:TEMP\data.txt } 'RS384' { $result = openssl dgst -sha384 -verify $PublicKey -signature $env:TEMP\sig.txt $env:TEMP\data.txt } 'RS512' { $result = openssl dgst -sha512 -verify $PublicKey -signature $env:TEMP\sig.txt $env:TEMP\data.txt } 'HS256' { Remove-Item -Path $env:TEMP\sig.txt -Force $result = openssl dgst -sha256 -mac HMAC -macopt key:$Secret -out "$env:TEMP\sig.txt" "$env:TEMP\data.txt" } 'HS384' { Remove-Item -Path $env:TEMP\sig.txt -Force $result = openssl dgst -sha384 -mac HMAC -macopt key:$Secret -out "$env:TEMP\sig.txt" "$env:TEMP\data.txt" } 'HS512' { Remove-Item -Path $env:TEMP\sig.txt -Force $result = openssl dgst -sha512 -mac HMAC -macopt key:$Secret -out "$env:TEMP\sig.txt" "$env:TEMP\data.txt" } Default { throw [System.ArgumentOutOfRangeException]::new("The JWT uses an unsupported algorithm.") } } #endregion if ($PSBoundParameters.ContainsKey('Secret')) { $content = Get-Content -Path $env:TEMP\sig.txt | Where-Object { $_ -match '(?<=\= )\w*$' } $bytes = [System.Text.Encoding]::UTF8.GetBytes($Matches[0]) $rsa_Base64 = [System.Convert]::ToBase64String($bytes) $result = $preparedSignature -eq $rsa_Base64 } } catch [System.Management.Automation.MethodException] { throw [System.Management.Automation.MethodException]::new($_.Exception.Message) } finally { Remove-Item -Path $env:TEMP\data.txt -Force Remove-Item -Path $env:TEMP\sig.txt -Force } } end { Write-Output -InputObject $result } } |