Why does a ECDSA-signed JWT in .NET fail validation in PHP when using OpenSSL, even with matching keys and algorithms?
- In .NET using
System.Security.CryptographyandSystem.IdentityModel.Tokens.Jwtpackages. - In PHP using
OpenSSLextension andFirebase's JWTlibrary. - Algo: ECDSA(ES256)
- Public key format: PEM
My example .NET code to generate JWT:
// ECDSA-signed JWT
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Security.Cryptography;
using Microsoft.IdentityModel.Tokens;
var privateKey = ECDsa.Create(ECCurve.NamedCurves.nistP256); // ES256
var securityKey = new ECDsaSecurityKey(privateKey) { KeyId = "1" };
var credentials = new SigningCredentials(securityKey, "ES256");
var token = new JwtSecurityToken(
issuer: "https://example.com",
audience: "https://example.com",
claims: new[] { new Claim("test", "value") },
expires: DateTime.UtcNow.AddHours(1),
signingCredentials: credentials
);
var jwt = new JwtSecurityTokenHandler().WriteToken(token);
Console.WriteLine("JWT (will fail in PHP): " + jwt);
Console.Read();
My example PHP code to consume JWT:
<?php
require 'vendor/autoload.php';
use FirebaseJWTJWT;
use FirebaseJWTKey;
$jwt = '<JWT STRING HERE>'; // From .NET
$publicKey = openssl_pkey_get_public('path/to/public_key.pem'); // PEM-formatted public key.
try
{
$decoded = JWT::decode($jwt, new Key($publicKey, 'ES256'));
print_r($decoded);
}
catch (Exception $e)
{
echo 'Validation error: ' . $e->getMessage();
}
PHP output:
Validation error: OpenSSL error: error:1C800064:Provider routines::bad signature
My instructions to create EXTRA ECDSA PEM formatted public-key for JWT:
# Generate private-key.
openssl ecparam -name prime256v1 -genkey -noout -out ec-private-key.pem
# Extract public-key from private-key.
openssl ec -in ec-private-key.pem -pubout -out ec-public-key.pem
Output files:
- ec-private-key.pem (private)
- ec-public-key.pem (public, for JWT validation).
Any idea why this happens?