Skip to content

Commit 213924f

Browse files
authored
feat: add support for W3C ES256K (#462)
1 parent 0178679 commit 213924f

File tree

6 files changed

+28
-7
lines changed

6 files changed

+28
-7
lines changed

Diff for: src/JWK.php

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class JWK
2626
private const ASN1_BIT_STRING = 0x03;
2727
private const EC_CURVES = [
2828
'P-256' => '1.2.840.10045.3.1.7', // Len: 64
29+
'secp256k1' => '1.3.132.0.10', // Len: 64
2930
// 'P-384' => '1.3.132.0.34', // Len: 96 (not yet supported)
3031
// 'P-521' => '1.3.132.0.35', // Len: 132 (not supported)
3132
];

Diff for: src/JWT.php

+8-7
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class JWT
5555
public static $supported_algs = [
5656
'ES384' => ['openssl', 'SHA384'],
5757
'ES256' => ['openssl', 'SHA256'],
58+
'ES256K' => ['openssl', 'SHA256'],
5859
'HS256' => ['hash_hmac', 'SHA256'],
5960
'HS384' => ['hash_hmac', 'SHA384'],
6061
'HS512' => ['hash_hmac', 'SHA512'],
@@ -132,8 +133,8 @@ public static function decode(
132133
// See issue #351
133134
throw new UnexpectedValueException('Incorrect key for this algorithm');
134135
}
135-
if ($header->alg === 'ES256' || $header->alg === 'ES384') {
136-
// OpenSSL expects an ASN.1 DER sequence for ES256/ES384 signatures
136+
if (\in_array($header->alg, ['ES256', 'ES256K', 'ES384'], true)) {
137+
// OpenSSL expects an ASN.1 DER sequence for ES256/ES256K/ES384 signatures
137138
$sig = self::signatureToDER($sig);
138139
}
139140
if (!self::verify("{$headb64}.{$bodyb64}", $sig, $key->getKeyMaterial(), $header->alg)) {
@@ -170,8 +171,8 @@ public static function decode(
170171
*
171172
* @param array<mixed> $payload PHP array
172173
* @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $key The secret key.
173-
* @param string $alg Supported algorithms are 'ES384','ES256', 'HS256', 'HS384',
174-
* 'HS512', 'RS256', 'RS384', and 'RS512'
174+
* @param string $alg Supported algorithms are 'ES384','ES256', 'ES256K', 'HS256',
175+
* 'HS384', 'HS512', 'RS256', 'RS384', and 'RS512'
175176
* @param string $keyId
176177
* @param array<string, string> $head An array with header elements to attach
177178
*
@@ -210,8 +211,8 @@ public static function encode(
210211
*
211212
* @param string $msg The message to sign
212213
* @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $key The secret key.
213-
* @param string $alg Supported algorithms are 'ES384','ES256', 'HS256', 'HS384',
214-
* 'HS512', 'RS256', 'RS384', and 'RS512'
214+
* @param string $alg Supported algorithms are 'ES384','ES256', 'ES256K', 'HS256',
215+
* 'HS384', 'HS512', 'RS256', 'RS384', and 'RS512'
215216
*
216217
* @return string An encrypted message
217218
*
@@ -238,7 +239,7 @@ public static function sign(
238239
if (!$success) {
239240
throw new DomainException('OpenSSL unable to sign data');
240241
}
241-
if ($alg === 'ES256') {
242+
if ($alg === 'ES256' || $alg === 'ES256K') {
242243
$signature = self::signatureFromDER($signature, 256);
243244
} elseif ($alg === 'ES384') {
244245
$signature = self::signatureFromDER($signature, 384);

Diff for: tests/JWTTest.php

+1
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,7 @@ public function provideEncodeDecode()
377377
[__DIR__ . '/data/ecdsa384-private.pem', __DIR__ . '/data/ecdsa384-public.pem', 'ES384'],
378378
[__DIR__ . '/data/rsa1-private.pem', __DIR__ . '/data/rsa1-public.pub', 'RS512'],
379379
[__DIR__ . '/data/ed25519-1.sec', __DIR__ . '/data/ed25519-1.pub', 'EdDSA'],
380+
[__DIR__ . '/data/secp256k1-private.pem', __DIR__ . '/data/secp256k1-public.pem', 'ES256K'],
380381
];
381382
}
382383

Diff for: tests/data/ec-jwkset.json

+9
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,15 @@
1717
"x": "mQa0q5FvxPRujxzFazQT1Mo2YJJzuKiXU3svOJ41jhw",
1818
"y": "jAz7UwIl2oOFk06kj42ZFMOXmGMFUGjKASvyYtibCH0",
1919
"alg": "ES256"
20+
},
21+
{
22+
"kty": "EC",
23+
"use": "sig",
24+
"crv": "secp256k1",
25+
"kid": "jwk3",
26+
"x": "EFpwNuP322bU3WP1DtJgx67L0CUV1MxNixqPVMH2L9Q",
27+
"y": "_fSTbijIJjpsqL16cIEvxxf3MaYMY8MbqEq066yV9ls",
28+
"alg": "ES256K"
2029
}
2130
]
2231
}

Diff for: tests/data/secp256k1-private.pem

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgC8ouvv1ZOmOjh5Nbwx6i
3+
3b35wWN+OEkW2hzm3BKAQJ2hRANCAAT9nYGLVP6Unm/LXOoyWhsKpalffMSr3EHV
4+
iUE8gVmj2/atnPkblx38Yj6bC3z1urERAB+JqgpWOAKaWcEYCUuO
5+
-----END PRIVATE KEY-----

Diff for: tests/data/secp256k1-public.pem

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
-----BEGIN PUBLIC KEY-----
2+
MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE/Z2Bi1T+lJ5vy1zqMlobCqWpX3zEq9xB
3+
1YlBPIFZo9v2rZz5G5cd/GI+mwt89bqxEQAfiaoKVjgCmlnBGAlLjg==
4+
-----END PUBLIC KEY-----

0 commit comments

Comments
 (0)