added predis and eseye back in.

This commit is contained in:
2020-12-25 11:28:41 +00:00
parent 0ddd298350
commit 017f72b42e
670 changed files with 60992 additions and 10 deletions

View File

@@ -0,0 +1,4 @@
# Contributing
This repository is a sub repository of [the JWT Framework](https://github.com/web-token/jwt-framework) project and is READ ONLY.
Please do not submit any Pull Requests here. It will be automatically closed.

View File

@@ -0,0 +1 @@
patreon: FlorentMorselli

View File

@@ -0,0 +1,3 @@
Please do not submit any Pull Requests here. It will be automatically closed.
You should submit it here: https://github.com/web-token/jwt-framework/pulls

View File

@@ -0,0 +1,80 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2020 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Jose\Component\Signature\Algorithm;
use function defined;
use function in_array;
use InvalidArgumentException;
use Jose\Component\Core\JWK;
use Jose\Component\Core\Util\ECKey;
use Jose\Component\Core\Util\ECSignature;
use LogicException;
use Throwable;
abstract class ECDSA implements SignatureAlgorithm
{
public function __construct()
{
if (!defined('OPENSSL_KEYTYPE_EC')) {
throw new LogicException('Elliptic Curve key type not supported by your environment.');
}
}
public function allowedKeyTypes(): array
{
return ['EC'];
}
public function sign(JWK $key, string $input): string
{
$this->checkKey($key);
if (!$key->has('d')) {
throw new InvalidArgumentException('The EC key is not private');
}
$pem = ECKey::convertPrivateKeyToPEM($key);
openssl_sign($input, $signature, $pem, $this->getHashAlgorithm());
return ECSignature::fromAsn1($signature, $this->getSignaturePartLength());
}
public function verify(JWK $key, string $input, string $signature): bool
{
$this->checkKey($key);
try {
$der = ECSignature::toAsn1($signature, $this->getSignaturePartLength());
$pem = ECKey::convertPublicKeyToPEM($key);
return 1 === openssl_verify($input, $der, $pem, $this->getHashAlgorithm());
} catch (Throwable $e) {
return false;
}
}
abstract protected function getHashAlgorithm(): string;
abstract protected function getSignaturePartLength(): int;
private function checkKey(JWK $key): void
{
if (!in_array($key->get('kty'), $this->allowedKeyTypes(), true)) {
throw new InvalidArgumentException('Wrong key type.');
}
foreach (['x', 'y', 'crv'] as $k) {
if (!$key->has($k)) {
throw new InvalidArgumentException(sprintf('The key parameter "%s" is missing.', $k));
}
}
}
}

View File

@@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2020 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Jose\Component\Signature\Algorithm;
final class ES256 extends ECDSA
{
public function name(): string
{
return 'ES256';
}
protected function getHashAlgorithm(): string
{
return 'sha256';
}
protected function getSignaturePartLength(): int
{
return 64;
}
}

View File

@@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2020 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Jose\Component\Signature\Algorithm;
final class ES384 extends ECDSA
{
public function name(): string
{
return 'ES384';
}
protected function getHashAlgorithm(): string
{
return 'sha384';
}
protected function getSignaturePartLength(): int
{
return 96;
}
}

View File

@@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2020 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Jose\Component\Signature\Algorithm;
final class ES512 extends ECDSA
{
public function name(): string
{
return 'ES512';
}
protected function getHashAlgorithm(): string
{
return 'sha512';
}
protected function getSignaturePartLength(): int
{
return 132;
}
}

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014-2019 Spomky-Labs
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,15 @@
ECDSA Based Signature Algorithms For JWT-Framework
==================================================
This repository is a sub repository of [the JWT Framework](https://github.com/web-token/jwt-framework) project and is READ ONLY.
**Please do not submit any Pull Request here.**
You should go to [the main repository](https://github.com/web-token/jwt-framework) instead.
# Documentation
The official documentation is available as https://web-token.spomky-labs.com/
# Licence
This software is release under [MIT licence](LICENSE).

View File

@@ -0,0 +1,169 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2020 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Jose\Component\Signature\Algorithm\Tests;
use Base64Url\Base64Url;
use Jose\Component\Core\JWK;
use Jose\Component\Signature\Algorithm\ES256;
use Jose\Component\Signature\Algorithm\ES384;
use Jose\Component\Signature\Algorithm\ES512;
use Jose\Component\Signature\Algorithm\SignatureAlgorithm;
use PHPUnit\Framework\TestCase;
/**
* @see https://tools.ietf.org/html/rfc6979#appendix-A.2.5
* @see https://tools.ietf.org/html/rfc6979#appendix-A.2.6
* @see https://tools.ietf.org/html/rfc6979#appendix-A.2.7
*
* Note that we only test
* * P-256 key with SHA-256
* * P-384 key with SHA-384
* * P-521 key with SHA-512
*
* Other curves or hash method combinaisons are not used by the Jot specification
*
* @group RFC6979
*
* @internal
*/
class ECDSAFromRFC6979Test extends TestCase
{
/**
* @param string $message
* @param string $signature
*
* @dataProvider dataWithVectors
*
* @test
*/
public function withVectors(SignatureAlgorithm $algorithm, $message, JWK $key, $signature): void
{
$is_valid = $algorithm->verify($key, $message, $signature);
static::assertTrue($is_valid);
}
public function dataWithVectors(): array
{
return [
[
new ES256(),
'sample',
new JWK([
'kty' => 'EC',
'crv' => 'P-256',
'd' => Base64Url::encode($this->convertHexToBin('C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721')),
'x' => Base64Url::encode($this->convertHexToBin('60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6')),
'y' => Base64Url::encode($this->convertHexToBin('7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299')),
]),
sprintf(
'%s%s',
$this->convertHexToBin('EFD48B2AACB6A8FD1140DD9CD45E81D69D2C877B56AAF991C34D0EA84EAF3716'),
$this->convertHexToBin('F7CB1C942D657C41D436C7A1B6E29F65F3E900DBB9AFF4064DC4AB2F843ACDA8')
),
],
[
new ES256(),
'test',
new JWK([
'kty' => 'EC',
'crv' => 'P-256',
'd' => Base64Url::encode($this->convertHexToBin('C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721')),
'x' => Base64Url::encode($this->convertHexToBin('60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6')),
'y' => Base64Url::encode($this->convertHexToBin('7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299')),
]),
sprintf(
'%s%s',
$this->convertHexToBin('F1ABB023518351CD71D881567B1EA663ED3EFCF6C5132B354F28D3B0B7D38367'),
$this->convertHexToBin('019F4113742A2B14BD25926B49C649155F267E60D3814B4C0CC84250E46F0083')
),
],
[
new ES384(),
'sample',
new JWK([
'kty' => 'EC',
'crv' => 'P-384',
'd' => Base64Url::encode($this->convertHexToBin('6B9D3DAD2E1B8C1C05B19875B6659F4DE23C3B667BF297BA9AA47740787137D896D5724E4C70A825F872C9EA60D2EDF5')),
'x' => Base64Url::encode($this->convertHexToBin('EC3A4E415B4E19A4568618029F427FA5DA9A8BC4AE92E02E06AAE5286B300C64DEF8F0EA9055866064A254515480BC13')),
'y' => Base64Url::encode($this->convertHexToBin('8015D9B72D7D57244EA8EF9AC0C621896708A59367F9DFB9F54CA84B3F1C9DB1288B231C3AE0D4FE7344FD2533264720')),
]),
sprintf(
'%s%s',
$this->convertHexToBin('94EDBB92A5ECB8AAD4736E56C691916B3F88140666CE9FA73D64C4EA95AD133C81A648152E44ACF96E36DD1E80FABE46'),
$this->convertHexToBin('99EF4AEB15F178CEA1FE40DB2603138F130E740A19624526203B6351D0A3A94FA329C145786E679E7B82C71A38628AC8')
),
],
[
new ES384(),
'test',
new JWK([
'kty' => 'EC',
'crv' => 'P-384',
'd' => Base64Url::encode($this->convertHexToBin('6B9D3DAD2E1B8C1C05B19875B6659F4DE23C3B667BF297BA9AA47740787137D896D5724E4C70A825F872C9EA60D2EDF5')),
'x' => Base64Url::encode($this->convertHexToBin('EC3A4E415B4E19A4568618029F427FA5DA9A8BC4AE92E02E06AAE5286B300C64DEF8F0EA9055866064A254515480BC13')),
'y' => Base64Url::encode($this->convertHexToBin('8015D9B72D7D57244EA8EF9AC0C621896708A59367F9DFB9F54CA84B3F1C9DB1288B231C3AE0D4FE7344FD2533264720')),
]),
sprintf(
'%s%s',
$this->convertHexToBin('8203B63D3C853E8D77227FB377BCF7B7B772E97892A80F36AB775D509D7A5FEB0542A7F0812998DA8F1DD3CA3CF023DB'),
$this->convertHexToBin('DDD0760448D42D8A43AF45AF836FCE4DE8BE06B485E9B61B827C2F13173923E06A739F040649A667BF3B828246BAA5A5')
),
],
// A zero has been added at the beginning of each value from the RFC (cannot convert to binary of not an even length).
[
new ES512(),
'sample',
new JWK([
'kty' => 'EC',
'crv' => 'P-521',
'd' => Base64Url::encode($this->convertHexToBin('00FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B83538')),
'x' => Base64Url::encode($this->convertHexToBin('01894550D0785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD371123D46E45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F5023A4')),
'y' => Base64Url::encode($this->convertHexToBin('00493101C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A28A0DB25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDFCF5')),
]),
sprintf(
'%s%s',
$this->convertHexToBin('00C328FAFCBD79DD77850370C46325D987CB525569FB63C5D3BC53950E6D4C5F174E25A1EE9017B5D450606ADD152B534931D7D4E8455CC91F9B15BF05EC36E377FA'),
$this->convertHexToBin('00617CCE7CF5064806C467F678D3B4080D6F1CC50AF26CA209417308281B68AF282623EAA63E5B5C0723D8B8C37FF0777B1A20F8CCB1DCCC43997F1EE0E44DA4A67A')
),
],
[
new ES512(),
'test',
new JWK([
'kty' => 'EC',
'crv' => 'P-521',
'd' => Base64Url::encode($this->convertHexToBin('00FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B83538')),
'x' => Base64Url::encode($this->convertHexToBin('01894550D0785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD371123D46E45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F5023A4')),
'y' => Base64Url::encode($this->convertHexToBin('00493101C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A28A0DB25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDFCF5')),
]),
sprintf(
'%s%s',
$this->convertHexToBin('013E99020ABF5CEE7525D16B69B229652AB6BDF2AFFCAEF38773B4B7D08725F10CDB93482FDCC54EDCEE91ECA4166B2A7C6265EF0CE2BD7051B7CEF945BABD47EE6D'),
$this->convertHexToBin('01FBD0013C674AA79CB39849527916CE301C66EA7CE8B80682786AD60F98F7E78A19CA69EFF5C57400E3B3A0AD66CE0978214D13BAF4E9AC60752F7B155E2DE4DCE3')
),
],
];
}
/**
* @param string $data
*
* @return string
*/
private function convertHexToBin($data)
{
return hex2bin($data);
}
}

View File

@@ -0,0 +1,107 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2020 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Jose\Component\Signature\Algorithm\Tests;
use Jose\Component\Core\AlgorithmManager;
use Jose\Component\Core\JWK;
use Jose\Component\Signature\Algorithm\ES512;
use Jose\Component\Signature\JWSBuilder;
use Jose\Component\Signature\JWSVerifier;
use Jose\Component\Signature\Serializer;
use PHPUnit\Framework\TestCase;
/**
* @see https://tools.ietf.org/html/rfc7520#section-4.3
*
* @group RFC7520
* @group unit
*
* @internal
*/
class ECDSAFromRFC7520Test extends TestCase
{
/**
* Please note that we cannot create the signature and get the same result as the example (ECDSA signatures are always different).
* This test case create a signature and verifies it.
* Then the output given in the RFC is used and verified.
* This way, we can say that the library is able to create/verify ECDSA signatures and verify signature from test vectors.
*
* @test
*/
public function eS512(): void
{
/*
* Payload
* EC public key
* @see https://tools.ietf.org/html/rfc7520#section-3.2
* @see https://tools.ietf.org/html/rfc7520#section-4.3.1
*/
$payload = "It\xe2\x80\x99s a dangerous business, Frodo, going out your door. You step onto the road, and if you don't keep your feet, there\xe2\x80\x99s no knowing where you might be swept off to.";
$private_key = new JWK([
'kty' => 'EC',
'kid' => 'bilbo.baggins@hobbiton.example',
'use' => 'sig',
'crv' => 'P-521',
'x' => 'AHKZLLOsCOzz5cY97ewNUajB957y-C-U88c3v13nmGZx6sYl_oJXu9A5RkTKqjqvjyekWF-7ytDyRXYgCF5cj0Kt',
'y' => 'AdymlHvOiLxXkEhayXQnNCvDX4h9htZaCJN34kfmC6pV5OhQHiraVySsUdaQkAgDPrwQrJmbnX9cwlGfP-HqHZR1',
'd' => 'AAhRON2r9cqXX1hg-RoI6R1tX5p2rUAYdmpHZoC1XNM56KtscrX6zbKipQrCW9CGZH3T4ubpnoTKLDYJ_fF3_rJt',
]);
/*
* Header
* @see https://tools.ietf.org/html/rfc7520#section-4.3.2
*/
$header = [
'alg' => 'ES512',
'kid' => 'bilbo.baggins@hobbiton.example',
];
$jwsBuilder = new JWSBuilder(
new AlgorithmManager([new ES512()])
);
$jwsVerifier = new JWSVerifier(
new AlgorithmManager([new ES512()])
);
$compactSerializer = new Serializer\CompactSerializer(
);
$jsonFlattenedSerializer = new Serializer\JSONFlattenedSerializer(
);
$jsonGeneralSerializer = new Serializer\JSONGeneralSerializer(
);
$jws = $jwsBuilder
->create()->withPayload($payload)
->addSignature($private_key, $header)
->build()
;
static::assertTrue($jwsVerifier->verifyWithKey($jws, $private_key, 0));
/*
* Header
* @see https://tools.ietf.org/html/rfc7520#section-4.3.3
*/
$expected_compact_json = 'eyJhbGciOiJFUzUxMiIsImtpZCI6ImJpbGJvLmJhZ2dpbnNAaG9iYml0b24uZXhhbXBsZSJ9.SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4.AE_R_YZCChjn4791jSQCrdPZCNYqHXCTZH0-JZGYNlaAjP2kqaluUIIUnC9qvbu9Plon7KRTzoNEuT4Va2cmL1eJAQy3mtPBu_u_sDDyYjnAMDxXPn7XrT0lw-kvAD890jl8e2puQens_IEKBpHABlsbEPX6sFY8OcGDqoRuBomu9xQ2';
$expected_flattened_json = '{"payload":"SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4","protected":"eyJhbGciOiJFUzUxMiIsImtpZCI6ImJpbGJvLmJhZ2dpbnNAaG9iYml0b24uZXhhbXBsZSJ9","signature":"AE_R_YZCChjn4791jSQCrdPZCNYqHXCTZH0-JZGYNlaAjP2kqaluUIIUnC9qvbu9Plon7KRTzoNEuT4Va2cmL1eJAQy3mtPBu_u_sDDyYjnAMDxXPn7XrT0lw-kvAD890jl8e2puQens_IEKBpHABlsbEPX6sFY8OcGDqoRuBomu9xQ2"}';
$expected_json = '{"payload":"SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4","signatures":[{"protected":"eyJhbGciOiJFUzUxMiIsImtpZCI6ImJpbGJvLmJhZ2dpbnNAaG9iYml0b24uZXhhbXBsZSJ9","signature":"AE_R_YZCChjn4791jSQCrdPZCNYqHXCTZH0-JZGYNlaAjP2kqaluUIIUnC9qvbu9Plon7KRTzoNEuT4Va2cmL1eJAQy3mtPBu_u_sDDyYjnAMDxXPn7XrT0lw-kvAD890jl8e2puQens_IEKBpHABlsbEPX6sFY8OcGDqoRuBomu9xQ2"}]}';
$loaded_compact_json = $compactSerializer->unserialize($expected_compact_json);
static::assertTrue($jwsVerifier->verifyWithKey($loaded_compact_json, $private_key, 0));
$loaded_flattened_json = $jsonFlattenedSerializer->unserialize($expected_flattened_json);
static::assertTrue($jwsVerifier->verifyWithKey($loaded_flattened_json, $private_key, 0));
$loaded_json = $jsonGeneralSerializer->unserialize($expected_json);
static::assertTrue($jwsVerifier->verifyWithKey($loaded_json, $private_key, 0));
}
}

View File

@@ -0,0 +1,205 @@
<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2020 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Jose\Component\Signature\Algorithm\Tests;
use Base64Url\Base64Url;
use InvalidArgumentException;
use Jose\Component\Core\JWK;
use Jose\Component\Signature\Algorithm\ES256;
use Jose\Component\Signature\Algorithm\ES384;
use Jose\Component\Signature\Algorithm\ES512;
use PHPUnit\Framework\TestCase;
/**
* @group ECDSA
* @group unit
*
* @internal
*/
class ECDSASignatureTest extends TestCase
{
/**
* @test
* @covers \Jose\Component\Signature\Algorithm\ES256
*/
public function invalidKey(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Wrong key type.');
$key = new JWK([
'kty' => 'RSA',
]);
$ecdsa = new ES256();
$data = 'Live long and Prosper.';
$ecdsa->sign($key, $data);
}
/**
* @test
* @covers \Jose\Component\Signature\Algorithm\ES256
*/
public function eS256Verify(): void
{
$key = new JWK([
'kty' => 'EC',
'crv' => 'P-256',
'x' => 'f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU',
'y' => 'x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0',
'd' => 'jpsQnnGQmL-YBIffH1136cspYG6-0iY7X1fCE9-E9LI',
]);
$ecdsa = new ES256();
$data = 'eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ';
$signature = 'DtEhU3ljbEg8L38VWAfUAqOyKAM6-Xx-F4GawxaepmXFCgfTjDxw5djxLa8ISlSApmWQxfKTUJqPP3-Kg6NU1Q';
$sign = $ecdsa->sign($key, $data);
static::assertTrue($ecdsa->verify($key, $data, $sign));
static::assertTrue($ecdsa->verify($key, $data, Base64Url::decode($signature)));
}
/**
* @test
* @covers \Jose\Component\Signature\Algorithm\ES256
*/
public function eS256SignVerify(): void
{
$key = new JWK([
'kty' => 'EC',
'crv' => 'P-256',
'x' => 'f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU',
'y' => 'x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0',
'd' => 'jpsQnnGQmL-YBIffH1136cspYG6-0iY7X1fCE9-E9LI',
]);
$ecdsa = new ES256();
$data = 'eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ';
$signature = $ecdsa->sign($key, $data);
static::assertTrue($ecdsa->verify($key, $data, $signature));
}
/**
* @test
* @covers \Jose\Component\Signature\Algorithm\ES256
*/
public function keyNotPrivate(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('The EC key is not private');
$key = new JWK([
'kty' => 'EC',
'crv' => 'P-256',
'x' => 'f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU',
'y' => 'x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0',
]);
$ecdsa = new ES256();
$data = 'eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ';
$ecdsa->sign($key, $data);
}
/**
* @test
* @covers \Jose\Component\Signature\Algorithm\ES384
*/
public function eS384SignVerify(): void
{
$key = new JWK([
'kty' => 'EC',
'crv' => 'P-384',
'd' => 'pcSSXrbeZEOaBIs7IwqcU9M_OOM81XhZuOHoGgmS_2PdECwcdQcXzv7W8-lYL0cr',
'x' => '6f-XZsg2Tvn0EoEapQ-ylMYNtsm8CPf0cb8HI2EkfY9Bqpt3QMzwlM7mVsFRmaMZ',
'y' => 'b8nOnRwmpmEnvA2U8ydS-dbnPv7bwYl-q1qNeh8Wpjor3VO-RTt4ce0Pn25oGGWU',
]);
$ecdsa = new ES384();
$data = 'eyJhbGciOiJFUzUxMiJ9.UGF5bG9hZA';
$signature = $ecdsa->sign($key, $data);
static::assertTrue($ecdsa->verify($key, $data, $signature));
}
/**
* @test
* @covers \Jose\Component\Signature\Algorithm\ES512
*/
public function eS512Verify(): void
{
$key = new JWK([
'kty' => 'EC',
'crv' => 'P-521',
'x' => 'AekpBQ8ST8a8VcfVOTNl353vSrDCLLJXmPk06wTjxrrjcBpXp5EOnYG_NjFZ6OvLFV1jSfS9tsz4qUxcWceqwQGk',
'y' => 'ADSmRA43Z1DSNx_RvcLI87cdL07l6jQyyBXMoxVg_l2Th-x3S1WDhjDly79ajL4Kkd0AZMaZmh9ubmf63e3kyMj2',
'd' => 'AY5pb7A0UFiB3RELSD64fTLOSV_jazdF7fLYyuTw8lOfRhWg6Y6rUrPAxerEzgdRhajnu0ferB0d53vM9mE15j2C',
]);
$ecdsa = new ES512();
$data = 'eyJhbGciOiJFUzUxMiJ9.UGF5bG9hZA';
$signature = 'AdwMgeerwtHoh-l192l60hp9wAHZFVJbLfD_UxMi70cwnZOYaRI1bKPWROc-mZZqwqT2SI-KGDKB34XO0aw_7XdtAG8GaSwFKdCAPZgoXD2YBJZCPEX3xKpRwcdOO8KpEHwJjyqOgzDO7iKvU8vcnwNrmxYbSW9ERBXukOXolLzeO_Jn';
$sign = $ecdsa->sign($key, $data);
static::assertTrue($ecdsa->verify($key, $data, $sign));
static::assertTrue($ecdsa->verify($key, $data, Base64Url::decode($signature)));
}
/**
* @test
* @covers \Jose\Component\Signature\Algorithm\ES512
*/
public function eS512SignVerify(): void
{
$key = new JWK([
'kty' => 'EC',
'crv' => 'P-521',
'x' => 'AekpBQ8ST8a8VcfVOTNl353vSrDCLLJXmPk06wTjxrrjcBpXp5EOnYG_NjFZ6OvLFV1jSfS9tsz4qUxcWceqwQGk',
'y' => 'ADSmRA43Z1DSNx_RvcLI87cdL07l6jQyyBXMoxVg_l2Th-x3S1WDhjDly79ajL4Kkd0AZMaZmh9ubmf63e3kyMj2',
'd' => 'AY5pb7A0UFiB3RELSD64fTLOSV_jazdF7fLYyuTw8lOfRhWg6Y6rUrPAxerEzgdRhajnu0ferB0d53vM9mE15j2C',
]);
$ecdsa = new ES512();
$data = 'eyJhbGciOiJFUzUxMiJ9.UGF5bG9hZA';
$signature = $ecdsa->sign($key, $data);
static::assertTrue($ecdsa->verify($key, $data, $signature));
}
/**
* @test
* @covers \Jose\Component\Signature\Algorithm\ES256
*/
public function badSignature(): void
{
$key = new JWK([
'kty' => 'EC',
'crv' => 'P-256',
'x' => 'f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU',
'y' => 'x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0',
]);
$ecdsa = new ES256();
$data = 'eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ';
$signature = 'DtEhU3ljbEg8L38VWAfUAqOyKAM6-Xx-F4GawxaepmXFCgfTjDxw5djxLa8ISlSApmWQxfKTUJqPP3';
static::assertFalse($ecdsa->verify($key, $data, Base64Url::decode($signature)));
}
}

View File

@@ -0,0 +1,42 @@
{
"name": "web-token/jwt-signature-algorithm-ecdsa",
"description": "ECDSA Based Signature Algorithms the JWT Framework.",
"type": "library",
"license": "MIT",
"keywords": ["JWS", "JWT", "JWE", "JWA", "JWK", "JWKSet", "Jot", "Jose", "RFC7515", "RFC7516", "RFC7517", "RFC7518", "RFC7519", "RFC7520", "Bundle", "Symfony"],
"homepage": "https://github.com/web-token",
"authors": [
{
"name": "Florent Morselli",
"homepage": "https://github.com/Spomky"
},{
"name": "All contributors",
"homepage": "https://github.com/web-token/jwt-framework/contributors"
}
],
"autoload": {
"psr-4": {
"Jose\\Component\\Signature\\Algorithm\\": ""
}
},
"require": {
"ext-openssl": "*",
"web-token/jwt-signature": "^2.0"
},
"require-dev": {
"phpunit/phpunit": "^8.0"
},
"extra": {
"branch-alias": {
"v1.0": "1.0.x-dev",
"v1.1": "1.1.x-dev",
"v1.2": "1.2.x-dev",
"v1.3": "1.3.x-dev",
"v2.0": "2.0.x-dev",
"v2.1": "2.1.x-dev"
}
},
"config": {
"sort-packages": true
}
}

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
backupGlobals="false"
backupStaticAttributes="false"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="true"
bootstrap="vendor/autoload.php"
colors="true">
<testsuites>
<testsuite name="Test Suite">
<directory>./Tests/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">./</directory>
<exclude>
<directory>./vendor</directory>
<directory>./Tests</directory>
<directory suffix="Test.php">./src</directory>
</exclude>
</whitelist>
</filter>
</phpunit>