Functions/Test-JwtSignature.ps1
function Test-JwtSignature { <# .SYNOPSIS Validates a JSON Web Token digital signature. .DESCRIPTION Validates a JSON Web Token digital signature only (no payload) for either RSA or HMAC signed JSON Web Tokens. .PARAMETER JsonWebToken The JSON Web Token containing the digital signature to be verified. .PARAMETER HashAlgorithm The RSA hash algorithim for the signature. Acceptable values are SHA256, SHA384, and SHA512. Default value is SHA256. .PARAMETER VerificationCertificate The certificate that will be used to verify the signature of the JSON Web Token. The private key is NOT needed for signature verification. .PARAMETER Key This is the secret key used to generate an HMAC signature. .PARAMETER JsonWebKey The JSON Web Key (X509 certificate public key) to verify the signature of the JSON Web Token per RFC 7517. .EXAMPLE $jwt = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4QzVkRTlFMDNBNTQ0MDVBQkI2QmEyNDJENjI5MDU0MiIsImlhdCI6MTU5MjU4MTA4OSwiZXhwIjoxNTkyNTgxMzg5LCJzdWIiOiJtZUBjb21wYW55LmNvbSJ9.PkfNMxLIk0qaynr373qxgWR8lTNE5BLApFYhcG3TpK0" Test-JwtSignature -JsonWebToken $jwt -HashAlgorithm SHA256 -Key "secret" Verifies a digital signature for an HAMC signed JSON Web Token against a key with a value of 'secret' (minus the quotes). .EXAMPLE $cert = Get-Item -Path "Cert:\CurrentUser\My\B31F009EEEEDDFAE34E977626E5A902600CF118C" $jwt = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6InN4OEFudTd0MzY0MDZYZGlibHFRSmdEUEVZdyIsIng1dCI6InN4OEFudTd0MzY0MDZYZGlibHFRSmdEUEVZdyJ9.eyJzdWIiOiJtZUBjb21wYW55LmNvbSIsImp0aSI6Ijk4NWQyNGNDOTZDMjQxMTA5N0E3NjAzMGY1OTM4RGQzIiwiaWF0IjoxNTkyNTgwOTA1LCJuYmYiOjE1OTI1ODA5MDUsImV4cCI6MTU5MjU4MTIwNX0.whJap3yJIYLIZ4BrK4tVHQVARGstI_omkoo2odOaSpTXZRh104Kyv7J3kiRPaNWKM7t_rpEVylmX-rzY_k_-d7auysVgQL2d-xNa8ZJGmjEemniPy2qRjbpdKDONlija7sbt_7E2n6_0kiwOiu31NemVr1EoWnpGLQeSfgjExuQPHatoKmi5UfijG0P4pWeo3xYyukYE14XOVGYI0ym3yl7gh7YUq9YkKZHvnMulzUoXWImZQ3_0ihC4CwD7QfqKbBuYGCAFtfJ55WHc_iX9EjgVS69aPLIciQmRtvr-xkVG4QApKTLb5NS5dJHKwVxvDojb2OBH5bQM5PMGxpRcIA" Test-JwtSignature -JsonWebToken $jwt -HashAlgorithm SHA256 -VerificationCertificate $cert Verifies a digital signature for an RSA signed JSON Web Token against a certificate with thumbprint B31F009EEEEDDFAE34E977626E5A902600CF118C. .EXAMPLE $jwt = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IjJ5Q3Zabms3azhXNjZ3UjJMWFI5V0Nzd2hBYyIsImtpZCI6IjJ5Q3Zabms3azhXNjZ3UjJMWFI5V0Nzd2hBYyJ9.eyJpYXQiOjE2MTgyNTAzODksIm5iZiI6MTYxODI1MDM4OSwiZXhwIjoxNjE4MjU1MTg5LCJzdWIiOiJ0b255In0.X-RZm-3Hto5U-8Q-Wp1ggqWTFPkO5-Cz9lzoKsH5-1RR9GOrGPuWn-bjIv1YJ46h5Bw-KpiX-dOS47TAq2A0BWdAwczLVA6pzha1WswkT_u3cO1_KSoOjD9qFLjCgk-ns7A48iXpNcOoPBFXgfx8G0rRK68sSnokJ7N2NH-YNUOjg3U7DNJ_-iz8WZ5dNlOvpDsTy0BHMX-lho18sUmakUNpadJr-oD7BXIp--Z57UERBFibppaoxseYRo3VfmhgHibTxP-39mcxU6sH9a99fEEt80hj4w6rZobRxZV-pFPS22B8TBAfVf8L9faMLaXmgV7xtQohqQZgL6oKdJzFPQ" $jwk = ' { "kty": "RSA", "use": "sig", "e": "AQAB", "n": "0yvTvlqT5yrk6lDzmK5_i6e-NKW4Bw8J9U62rcWI4IAr-vKaNqitmSwVLr2jJu29xQ__W22iGu584A82AS5N5YrwA6Rek-7WuHinwupFtCN-cCTzJlAcXUxyU7H0LfFxsXS1LUxSl7F_liIKH81QFE5RvI97R9bmbCn_BXpK4pHnTBGJigA8gJQ0U__YFk7AOSFUBeursQfCVPID99FpQ6pyj-h9WgdOneAfWde4SM1Pnovw59T2UT-JO-ObA5WOtvl0xW21djhhBRusVGWJuncNElhhRpUqNSOcsNQVe026zw8dX1wiMs9migQmz_LokH1bHENIuybdK9xBhXRRbw", "kid": "2yCvZnk7k8W66wR2LXR9WCswhAc" } ' Test-JwtSignature -JsonWebToken $jwt -HashAlgorithm SHA256 -JsonWebKey $jwk Verifies a JSON Web Token's digital signature against a JSON Web Key. .OUTPUTS System.Boolean .LINK https://tools.ietf.org/html/rfc7515 https://tools.ietf.org/html/rfc7517 https://tools.ietf.org/html/rfc7519 New-JwtSignature New-JsonWebKeySet #> [CmdletBinding()] [OutputType([System.Boolean])] Param ( [Parameter(Mandatory=$true,ValueFromPipeline=$false,Position=0)] [ValidateLength(16,8192)][Alias("JWT", "Token")][String]$JsonWebToken, [Parameter(Mandatory=$true,Position=1)][ValidateSet("SHA256","SHA384","SHA512")][String]$HashAlgorithm, [Parameter(Mandatory=$true,ParameterSetName="RSA",Position=2)][Alias("Certificate", "Cert")] [System.Security.Cryptography.X509Certificates.X509Certificate2]$VerificationCertificate, [Parameter(Mandatory=$true,ParameterSetName="HMAC",Position=2)][ValidateLength(4,32768)][String]$Key, [Parameter(Mandatory=$true,ParameterSetName="JWK",Position=2)][Alias("jwk")][ValidateLength(12, 1073741791)][String]$JsonWebKey ) BEGIN { $decodeExceptionMessage = "Unable to decode JWT." $ArgumentException = New-Object -TypeName ArgumentException -ArgumentList $decodeExceptionMessage } PROCESS { [bool]$signatureVerifies = $false [bool]$isValidJwt = Test-JwtStructure -JsonWebToken $JsonWebToken -VerifySignaturePresent if (-not($isValidJwt)) { Write-Error -Exception $ArgumentException -Category InvalidArgument -ErrorAction Stop } $jwtHeader = Get-JsonWebTokenHeader -JsonWebToken $JsonWebToken -AsEncodedString $jwtPayload = Get-JsonWebTokenPayload -JsonWebToken $JsonWebToken -AsEncodedString $jwtSig = Get-JsonWebTokenSignature -JsonWebToken $JsonWebToken -AsEncodedString $jwt = "{0}.{1}" -f $jwtHeader, $jwtPayload if ($PSCmdlet.ParameterSetName -eq "HMAC") { [string]$hmacSig = "" try { $hmacSig = New-JwtSignature -JsonWebToken $jwt -Key $Key -HashAlgorithm $HashAlgorithm -ErrorAction Stop } catch { $signatureExceptionMessage = "Unable to generate signature for given header and payload." $ArgumentException = New-Object -TypeName ArgumentException -ArgumentList $signatureExceptionMessage Write-Error -Exception $ArgumentException -Category InvalidArgument -ErrorAction Stop } if ($hmacSig -eq $jwtSig) { $signatureVerifies = $true } } elseif ($PSCmdlet.ParameterSetName -eq "RSA") { if ($null -ne $VerificationCertificate.PrivateKey.KeyExchangeAlgorithm) { Write-Warning -Message "It is not necessary to perform signature verification with a certificate that has private key!" } try { $signatureVerifies = Test-JwtRsaSignature -JsonWebToken $JsonWebToken -VerificationCertificate $VerificationCertificate -HashAlgorithm $HashAlgorithm -ErrorAction Stop } catch { Write-Error -Exception $_.Exception -ErrorAction Stop } } else # ParameterSetName -eq JWK { try { $signatureVerifies = Test-JwtJwkSignature -JsonWebToken $JsonWebToken -JsonWebKey $JsonWebKey -HashAlgorithm SHA256 -ErrorAction Stop } catch { Write-Error -Exception $_.Exception -ErrorAction Stop } } return $signatureVerifies } } |