Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
composer require web-token/jwt-signatureeyJhbGciOiJFUzUxMiJ9.UGF5bG9hZA.AdwMgeerwtHoh-l192l60hp9wAHZFVJbLfD_UxMi70cwnZOYaRI1bKPWROc-mZZqwqT2SI-KGDKB34XO0aw_7XdtAG8GaSwFKdCAPZgoXD2YBJZCPEX3xKpRwcdOO8KpEHwJjyqOgzDO7iKvU8vcnwNrmxYbSW9ERBXukOXolLzeO_Jn{
"payload": "SW4gb3VyIHZpbGxhZ2UsIGZvbGtzIHNheSBHb2QgY3J1bWJsZXMgdXAgdGhlIG9sZCBtb29uIGludG8gc3RhcnMu",
"protected": "eyJhbGciOiJFUzI1NiJ9",
"header": {
"kid": "myEcKey"
},
"signature": "b7V2UpDPytr-kMnM_YjiQ3E0J2ucOI9LYA7mt57vccrK1rb84j9areqgQcJwOA00aWGoz4hf6sMTBfobdcJEGg"
}{
"payload": "SW4gb3VyIHZpbGxhZ2UsIGZvbGtzIHNheSBHb2QgY3J1bWJsZXMgdXAgdGhlIG9sZCBtb29uIGludG8gc3RhcnMu",
"signatures": [
{
"protected": "eyJhbGciOiJSUzI1NiJ9",
"header": {
"kid": "myRsaKey"
},
"signature": "B04c24gSnpVm1Z-_bemfyNMCpZm6Knj1yB-yzaIOvijsWfDgoF_mSJccTIbzapNgwJudnobr5iDOfZWiRR9iqCyDJLe5M1S40vFF7MFEI3JecYRgrRc6n1lTkYLMRyVq48BwbQlmKgPqmK9drun3agklsr0FmgNx65pfmcnlYdXsgwxf8WbgppefrlrMImp-98-dNtBcUL8ce1aOjbcyVFjGMCzpm3JerQqIzWQvEwBstnMEQle73KHcyx_nsTmlzY70CaydbRTsciOATL7WfiMwuX1q9Y2NIpTg3CbOTWKdwjh7iyfiAKQxNBaF2mApnqj9hjpf8GwR-CfxAzJtPg"
},
{
"protected": "eyJhbGciOiJFUzI1NiJ9",
"header": {
"kid": "myEcKey"
},
"signature": "2cbugKq0ERaQMh01n2B-86EZFYleeMf8bsccaQMxzOxAg14PxfjR3IImvodTJYqkmfBJYW203etz2-7ZtJUOGw"
},
{
"protected": "eyJhbGciOiJIUzI1NiJ9",
"header": {
"kid": "myMacKey"
},
"signature": "e7R9gjx0RsUNa3c7qd8k9mQGEhtcG8vsN1W7jbLb2MA"
}
]
}<?php
require_once 'vendor/autoload.php';
use Jose\Component\Core\Converter\StandardConverter;
use Jose\Component\Signature\Serializer;
$jsonConverter = new StandardConverter();
$manager = Serializer\JWSSerializerManager::create([
new Serializer\CompactSerializer($jsonConverter),
new Serializer\JSONFlattenedSerializer($jsonConverter),
new Serializer\JSONGeneralSerializer($jsonConverter),
]);
// Serializes the second signature (index = 1) of the variable $jws (JWS object) into JSON Flattened serialization mode.
$token = $manager->serialize('jws_json_flattened', $jws, 1);
// Retrieve the JWS object from a token
$jws = $manager->unserialize($token);eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.UGhIOguC7IuEvf_NPVaXsGMoLOmwvc1GyqlIKOK1nN94nHPoltGRhWhw7Zx0-kFm1NJn8LE9XShH59_i8J0PH5ZZyNfGy2xGdULU7sHNF6Gp2vPLgNZ__deLKxGHZ7PcHALUzoOegEI-8E66jX2E4zyJKx-YxzZIItRzC5hlRirb6Y5Cl_p-ko3YvkkysZIFNPccxRU7qve1WYPxqbb2Yw8kZqa2rMWI5ng8OtvzlV7elprCbuPhcCdZ6XDP0_F8rkXds2vE4X-ncOIM8hAYHHi29NX0mcKiRaD0-D-ljQTP-cFPgwCp6X-nZZd9OHBv-B3oWh2TbqmScqXMR4gp_A.AxY8DCtDaGlsbGljb3RoZQ.KDlTtXchhZTGufMYmOYGS4HffxPSUrfmqCHXaI9wOGY.9hH0vgRfYgPnAHOd8stkvw{
"protected":"eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0",
"unprotected":{"jku":"https://server.example.com/keys.jwks"},
"header":{"alg":"A128KW","kid":"7"},
"encrypted_key":"6KB707dM9YTIgHtLvtgWQ8mKwboJW3of9locizkDTHzBC2IlrT1oOQ",
"iv":"AxY8DCtDaGlsbGljb3RoZQ",
"ciphertext":"KDlTtXchhZTGufMYmOYGS4HffxPSUrfmqCHXaI9wOGY",
"tag":"Mz-VPPyU4RlcuYv1IwIvzw"
} {
"protected":"eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0",
"unprotected":{"jku":"https://server.example.com/keys.jwks"},
"recipients":[
{
"header":{"alg":"RSA1_5","kid":"2011-04-29"},
"encrypted_key":"UGhIOguC7IuEvf_NPVaXsGMoLOmwvc1GyqlIKOK1nN94nHPoltGRhWhw7Zx0-kFm1NJn8LE9XShH59_i8J0PH5ZZyNfGy2xGdULU7sHNF6Gp2vPLgNZ__deLKxGHZ7PcHALUzoOegEI-8E66jX2E4zyJKx-YxzZIItRzC5hlRirb6Y5Cl_p-ko3YvkkysZIFNPccxRU7qve1WYPxqbb2Yw8kZqa2rMWI5ng8OtvzlV7elprCbuPhcCdZ6XDP0_F8rkXds2vE4X-ncOIM8hAYHHi29NX0mcKiRaD0-D-ljQTP-cFPgwCp6X-nZZd9OHBv-B3oWh2TbqmScqXMR4gp_A"
},
{
"header":{"alg":"A128KW","kid":"7"},
"encrypted_key":"6KB707dM9YTIgHtLvtgWQ8mKwboJW3of9locizkDTHzBC2IlrT1oOQ"
}
],
"iv":"AxY8DCtDaGlsbGljb3RoZQ",
"ciphertext":"KDlTtXchhZTGufMYmOYGS4HffxPSUrfmqCHXaI9wOGY",
"tag":"Mz-VPPyU4RlcuYv1IwIvzw"
}<?php
require_once 'vendor/autoload.php';
use Jose\Component\Core\Converter\StandardConverter;
use Jose\Component\Encryption\Serializer;
$jsonConverter = new StandardConverter();
$manager = Serializer\JWESerializerManager::create([
new Serializer\CompactSerializer($jsonConverter),
new Serializer\JSONFlattenedSerializer($jsonConverter),
new Serializer\JSONGeneralSerializer($jsonConverter),
]);
// Serializes the second recipient (index = 1) of the variable $jwe (JWE object) into JSON Flattened serialization mode.
$token = $manager->serialize('jwe_json_flattened', $jwe, 1);
// Retrieve the JWE object from a token
$jwe = $manager->unserialize($token);$jwe = $jweBuilder
->create()
->withPayload('...')
->withSharedProtectedHeader([
'enc' => 'A256CBC-HS512',
'alg' => 'RSA-OAEP-256',
'zip' => 'DEF',
])
->addRecipient($recipient_key)
->withAAD('A,B,C,D')
->build();$jws = $jwsBuilder
->create()
->withPayload('...')
->addSignature($jwk, ['alg' => 'HS256'], ['description' => 'Small description here', 'author' => 'John Doe'])
->build();<?php
declare(strict_types=1);
namespace Acme\Algorithm;
use Base64Url\Base64Url;
use Jose\Component\Core\JWK;
use const Sodium\CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES;
/**
* This algorithm is a custom algorithm that use the ChaCha20 + Poly 1305 with a 192 bits nonce (IETF variant).
*/
final class ChaCha20Poly1305IETF implements KeyEncryption //The algorithm acts as a Key Encryption algorithm
{
/**
* {@inheritdoc}
*/
public function name(): string
{
return 'ChaCha20+Poly1305+IETF'; // The name of our algorithm. This name will be used in our JWE headers
}
/**
* {@inheritdoc}
*/
public function allowedKeyTypes(): array
{
return ['oct']; // Key types for this algorithm are octet keys
}
/**
* {@inheritdoc}
*/
public function encryptKey(JWK $key, string $cek, array $completeHeader, array &$additionalHeader): string
{
$this->checkKey($key); // We check the key
$kek = Base64Url::decode($key->get('k')); // We retrieve the secret
$nonce = random_bytes(CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES); // We create a nonce
$additionalHeader['nonce'] = Base64Url::encode($nonce); // We add the nonce to the header
return sodium_crypto_aead_chacha20poly1305_ietf_encrypt($cek, '', $nonce, $kek); // We return the encrypted CEK
}
/**
* {@inheritdoc}
*/
public function decryptKey(JWK $key, string $encrypted_cek, array $header): string
{
$this->checkKey($key); // We check the key
$this->checkAdditionalParameters($header); // We verify the nonce is in the headers
$nonce = Base64Url::decode($header['nonce']); // We retrieve the nonce
$kek = Base64Url::decode($key->get('k')); // an the secret
$decrypted = sodium_crypto_aead_chacha20poly1305_ietf_decrypt($encrypted_cek, '', $nonce, $kek); // We try to decrypt the CEK
if (false === $decrypted) { // If it fails we throw an exception
throw new \RuntimeException('Unable to decrypt.');
}
return $decrypted; // Otherwise we return the decrypted CEK
}
/**
* @param JWK $key
*/
protected function checkKey(JWK $key)
{
if (!in_array($key->get('kty'), $this->allowedKeyTypes())) {
throw new \InvalidArgumentException('Wrong key type.');
}
if (!$key->has('k')) {
throw new \InvalidArgumentException('The key parameter "k" is missing.');
}
}
/**
* @param array $header
*/
protected function checkAdditionalParameters(array $header)
{
foreach (['nonce'] as $k) {
if (!array_key_exists($k, $header)) {
throw new \InvalidArgumentException(sprintf('Parameter "%s" is missing.', $k));
}
}
}
/**
* {@inheritdoc}
*/
public function getKeyManagementMode(): string
{
return self::MODE_ENCRYPT; //Key Management Mode is 'enc'.
}
}$jws = $jwsBuilder
->create()
->withPayload('Hello World!')
->addSignature($jwk, ['alg' => 'HS256', 'b64' => false, 'crit' => ['b64']])
->build();$jws = $jwsBuilder
->create()
->withPayload('...')
->addSignature($signature_key1, ['alg' => 'HS256'])
->addSignature($signature_key2, ['alg' => 'RS384'])
->addSignature($signature_key3, ['alg' => 'ES512'])
->build();use Jose\Component\Core\Converter\StandardConverter;
use Jose\Component\Signature\Serializer;
// The JSON Converter.
$jsonConverter = new StandardConverter();
$manager = Serializer\JWSSerializerManager::create([
new Serializer\CompactSerializer($jsonConverter),
new Serializer\JsonFlattenedSerializer($jsonConverter),
new Serializer\JsonGeneralSerializer($jsonConverter),
]);
$tokenWithAllSignatures = $manager->serialize('jws_json_general', $jws);
$compactTokenWithSignatureAtIndex1 = $manager->serialize('jws_compact', $jws, 1);
$flattenedTokenWithSignatureAtIndex2 = $manager->serialize('jws_json_flattened', $jws, 2);$jwe = $jweBuilder
->create()
->withPayload('...')
->withSharedProtectedHeader(['enc' => 'A256GCM', 'alg' => 'A256KW'])
->withSharedHeader(['author' => 'John Doe'])
->addRecipient($recipient_public_key_1, ['message' => 'Hello World!'])
->addRecipient($recipient_public_key_2, ['description' => 'Nice song for you'])
->build();<?php
use Jose\Component\Core\AlgorithmManager;
use Jose\Component\Core\Converter\StandardConverter;
use Jose\Component\Core\JWK;
use Jose\Component\Signature\Algorithm\HS256;
use Jose\Component\Signature\JWSBuilder;
// The algorithm manager with the HS256 algorithm.
$algorithmManager = AlgorithmManager::create([
new HS256(),
]);
// Our key.
$jwk = JWK::create([
'kty' => 'oct',
'k' => 'dzI6nbW4OcNF-AtfxGAmuyz7IpHRudBI0WgGjZWgaRJt6prBn3DARXgUR8NVwKhfL43QBIU2Un3AvCGCHRgY4TbEqhOi8-i98xxmCggNjde4oaW6wkJ2NgM3Ss9SOX9zS3lcVzdCMdum-RwVJ301kbin4UtGztuzJBeg5oVN00MGxjC2xWwyI0tgXVs-zJs5WlafCuGfX1HrVkIf5bvpE0MQCSjdJpSeVao6-RSTYDajZf7T88a2eVjeW31mMAg-jzAWfUrii61T_bYPJFOXW8kkRWoa1InLRdG6bKB9wQs9-VdXZP60Q4Yuj_WZ-lO7qV9AEFrUkkjpaDgZT86w2g',
]);
// The JSON Converter.
$jsonConverter = new StandardConverter();
// We instantiate our JWS Builder.
$jwsBuilder = new JWSBuilder(
$jsonConverter,
$algorithmManager
);
// The payload we want to sign
$payload = $jsonConverter->encode([
'iat' => time(),
'nbf' => time(),
'exp' => time() + 3600,
'iss' => 'My service',
'aud' => 'Your application',
]);
$jws = $jwsBuilder
->create() // We want to create a new JWS
->withPayload($payload, true) // /!\ Here is the change! We set the payload and we indicate it is detached
->addSignature($jwk, ['alg' => 'HS256']) // We add a signature with a simple protected header
->build();<?php
use Jose\Component\Core\AlgorithmManager;
use Jose\Component\Core\Converter\StandardConverter;
use Jose\Component\Core\JWK;
use Jose\Component\Signature\Algorithm\HS256;
use Jose\Component\Signature\JWSVerifier;
use Jose\Component\Signature\Serializer\JWSSerializerManager;
use Jose\Component\Signature\Serializer\CompactSerializer;
// The algorithm manager with the HS256 algorithm.
$algorithmManager = AlgorithmManager::create([
new HS256(),
]);
// Our key.
$jwk = JWK::create([
'kty' => 'oct',
'k' => 'dzI6nbW4OcNF-AtfxGAmuyz7IpHRudBI0WgGjZWgaRJt6prBn3DARXgUR8NVwKhfL43QBIU2Un3AvCGCHRgY4TbEqhOi8-i98xxmCggNjde4oaW6wkJ2NgM3Ss9SOX9zS3lcVzdCMdum-RwVJ301kbin4UtGztuzJBeg5oVN00MGxjC2xWwyI0tgXVs-zJs5WlafCuGfX1HrVkIf5bvpE0MQCSjdJpSeVao6-RSTYDajZf7T88a2eVjeW31mMAg-jzAWfUrii61T_bYPJFOXW8kkRWoa1InLRdG6bKB9wQs9-VdXZP60Q4Yuj_WZ-lO7qV9AEFrUkkjpaDgZT86w2g',
]);
// The JSON Converter.
$jsonConverter = new StandardConverter();
// The serializer manager. We only use the JWS Compact Serialization Mode.
$serializerManager = JWSSerializerManager::create([
new CompactSerializer($jsonConverter),
]);
// We instantiate our JWS Verifier.
$jwsVerifier = new JWSVerifier(
$algorithmManager
);
// The detached payload
$payload = '{"iat":1507896992,"nbf":1507896992,"exp":1507900592,"iss":"My service","aud":"Your application"}';
// The input we want to check
$token = 'eyJhbGciOiJIUzI1NiJ9..eycp9PTdgO4WA-68-AMoHPwsKDr68NhjIQKz4lUkiI0';
// We try to load the token.
$jws = $serializerManager->unserialize($token);
// We verify the signature.
// /!\ The third argument is the detached payload.
$jwsVerifier->verifyWithKey($jws, $jwk, $payload);$jweBuilder
->create()
->withPayload('...')
->withSharedProtectedHeader(['enc' => 'A128GCM'])
->addRecipient($recipient_key_1, ['alg' => 'RSA1_5'])
->addRecipient($recipient_key_2, ['alg' => 'RSA-OAEP-256'])
->build();use Jose\Component\Encryption\NestedTokenLoader;
$nestedTokenLoader = new NestedTokenLoader($jweLoader, $jwsLoader);$jws = $nestedTokenLoader->load($token, $encryptionKeySet, $signatureKeySet, $signature);use Jose\Component\Encryption\NestedTokenBuilder;
$nestedTokenBuilder = new NestedTokenBuilder($jweLoader, $jweSerializerManager, $jwsLoader, $jwsSerializerManager);$token = $builder->create(
$payload, // The payload to protect
[[ // A list of signatures. 'key' is mandatory and at least one of 'protected_header'/'header' has to be set.
'key' => $signature_key, // The key used to sign. Mandatory.
'protected_header' => ['alg' => 'PS256'], // The protected header. Optional.
'header' => ['foo' => 'bar'], // The unprotected header. Optional.
]],
'jws_json_flattened', // The serialization mode for the JWS
['alg' => 'RSA-OAEP', 'enc' => 'A128GCM'], // The shared protected header. Optional.
['foo' => 'bar'], // The shared unprotected header. Optional.
[[ // A list of recipients. 'key' is mandatory.
'key' => $encryption_key, // The recipient key.
'header' => ['bar' => 'foo'], // The recipient unprotected header.
]],
'jwe_json_flattened' // The serialization mode for the JWE.
'1, 2, 3, 4' // Additional Authenticated Data (AAD). Optional.
);jose:
nested_token:
loaders:
loader_1:
signature_algorithms: ['PS256']
key_encryption_algorithms: ['RSA-OAEP']
content_encryption_algorithms: ['A128GCM']
jws_serializers: ['jws_compact']
jws_header_checkers: [...]
jwe_serializers: ['jwe_compact']
jwe_header_checkers: [...]
is_public: true
builders:
builder_1:
signature_algorithms: ['PS256']
key_encryption_algorithms: ['RSA-OAEP']
content_encryption_algorithms: ['A128GCM']
jws_serializers: ['jws_compact']
jwe_serializers: ['jwe_compact']
is_public: trueclass AcmeExtension extends Extension implements PrependExtensionInterface
{
...
public function prepend(ContainerBuilder $container)
{
ConfigurationHelper::addNestedTokenLoader($container, 'loader_1', ['jwe_compact'], ['RSA-OAEP'], ['A128GCM'], ['DEF'], [], ['jws_compact'], ['PS256'], [], true, []);
ConfigurationHelper::addNestedTokenBuilder($container, 'builder_1', ['jwe_compact'], ['RSA-OAEP'], ['A128GCM'], ['DEF'], ['jws_compact'], ['PS256'], true, []);
}
}