Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
composer require web-token/jwt-signature$jwe = $jweBuilder
->create()
->withPayload('...')
->withSharedProtectedHeader([
'enc' => 'A256CBC-HS512',
'alg' => 'RSA-OAEP-256',
'zip' => 'DEF',
])
->addRecipient($recipient_key)
->withAAD('A,B,C,D')
->build();<?php
// Returns all keys
$jwkset->all();
// Check if the key set has the key with the key ID 'KEY ID'.
$jwkset->has('KEY ID');
// Retreive the key with the key ID 'KEY ID'.
$jwkset->get('KEY ID');
// Counts the keys in the key set.
$jwkset->count(); // The method count($jwkset) has the same behaviour.
// Adds a key to the key set.
// /!\ As the JWKSet object is immutable, this method will create a new key set. The previous key set is unchanged.
$new_jwkset = $jwkset->with($jwk);
// Removes a key to the key set.
// /!\ As the JWKSet object is immutable, this method will create a new key set. The previous key set is unchanged.
$new_jwkset = $jwkset->without('KEY ID');
// Selects a key according to the requirements.
// The first argument is the key usage ("sig" of "enc")
// The second argument is the algorithm to be used (optional)
// The third argument is an associative array this constraints (optional)
$key = $jwkset->selectKey('sig', $algorithm, ['kid' => 'KEY ID']);
// You can iterate on a key set
foreach($jwkset as $kid => $jwk) {
// Action with the key done here
}
// The JWKSet object can be serialized into JSON
json_encode($jwkset);<?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
);use Jose\Component\Signature\Serializer\CompactSerializer;
$serializer = new CompactSerializer($jsonConverter); // The serializer
$token = $serializer->serialize($jws, 0); // We serialize the signature at index 0 (we only have one signature).composer require web-token/jwt-signature// The payload we want to sign. The payload MUST be a string hence we use our JSON Converter.
$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) // We set the payload
->addSignature($jwk, ['alg' => 'HS256']) // We add a signature with a simple protected header
->build(); // We build itcomposer require web-token/jwt-coreeyJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1MDc4OTY5OTIsIm5iZiI6MTUwNzg5Njk5MiwiZXhwIjoxNTA3OTAwNTkyLCJpc3MiOiJNeSBzZXJ2aWNlIiwiYXVkIjoiWW91ciBhcHBsaWNhdGlvbiJ9.eycp9PTdgO4WA-68-AMoHPwsKDr68NhjIQKz4lUkiI0services:
Acme\Bundle\Algorithm\FooAlgorihtm:
tags:
- {'name': 'jose.algorithm', 'alias': 'FOO'}$jws = $jwsBuilder
->create()
->withPayload('...')
->addSignature($jwk, ['alg' => 'HS256'], ['description' => 'Small description here', 'author' => 'John Doe'])
->build();composer require web-token/jwt-encryptioncomposer require web-token/jwt-encryption<?php
use Jose\Object\JWK;
$key = new JWK([
'kty' => 'RSA',
'n' => '0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw',
'e' => 'AQAB',
'alg' => 'RS256',
'kid' => '2011-04-29',
]);
$key->has('kty'); // true
$key->get('kty'); // RSA
$key->thumbprint('sha256'); // The Sha-256 thumbprint of the key: "NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs"
json_encode($key); // The key as a Json object: "{"kty":"RSA","n":"0vx7agoebGcQSuuPiLJXZptN9n...8awapJzKnqDKgw","e":"AQAB","alg":"RS256","kid":"2011-04-29"}"
$key->toPublic(); // Converts a private key to a public one (not relevant in this example as the key is public)
$key->getAll(); // All key parameters<?php
use Jose\Component\Core\JWK;
$key = new JWK([
'kty' => 'RSA',
'n' => '0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw',
'e' => 'AQAB',
'alg' => 'RS256',
'kid' => '2011-04-29',
]);
$key->has('kty'); // Unchanged
$key->get('kty'); // Unchanged
$key->thumbprint('sha256'); // Unchanged
json_encode($key); // Unchanged
$key->toPublic(); // Unchanged
$key->all(); // The method name changed.composer require web-token/jwt-console
composer require web-token/jwt-bundle// app/AppKernel.php
class AppKernel extends Kernel
{
public function registerBundles()
{
$bundles = [
...
new Jose\Bundle\JwtFramework\JwtFrameworkBundle(),
];
return $bundles;
}
...
}./bin/console$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);<?php
use Jose\Checker\CheckerManager;
use Jose\Checker\AudienceChecker;
use Jose\Checker\CriticalHeaderChecker;
$checkerManager = new CheckerManager();
$checkerManager->addHeaderChecker(new AudienceChecker('My Server'));
$checkerManager->addHeaderChecker(new CriticalHeaderChecker());
$checkerManager->checkJWS($jws, $signature_index);<?php
use Jose\Component\Checker\AudienceChecker;
use Jose\Component\Checker\HeaderCheckerManager;
use Jose\Component\Signature\JWSTokenSupport;
$checkerManager = new HeaderCheckerManager();
$checkerManager->add(new AudienceChecker('My Service'));
$checkerManager->addTokenTypeSupport(new TokenSupport());<?php
use Jose\Checker\CheckerManager;
use Jose\Checker\ExpirationTimeChecker;
use Jose\Checker\IssuedAtChecker;
use Jose\Checker\NotBeforeChecker;
$checkerManager = new CheckerManager();
$checkerManager->addClaimChecker(new ExpirationTimeChecker());
$checkerManager->addClaimChecker(new IssuedAtChecker());
$checkerManager->addClaimChecker(new NotBeforeChecker());
$checkerManager->checkJWS($jws, $signature_index);<?php
use Jose\Component\Checker\ClaimCheckerManager;
use Jose\Component\Checker\ExpirationTimeChecker;
use Jose\Component\Checker\IssuedAtChecker;
use Jose\Component\Checker\NotBeforeChecker;
$claimCheckerManager = new ClaimCheckerManager();
$claimCheckerManager->add(new ExpirationTimeChecker());
$claimCheckerManager->add(new IssuedAtChecker());
$claimCheckerManager->add(new NotBeforeChecker());
$claimCheckerManager->check($claims);parameters:
my_private_key: '%env(jwk:MY_PRIVATE_KEY)%'
my_public_keyset: '%env(jwkset:MY_PUBLIC_KEYSET)%'composer require web-token/jwt-key-mgmt<?php
use Jose\Component\Core\AlgorithmManager;
use Jose\Component\Signature\Algorithm\PS256;
use Jose\Component\Signature\Algorithm\ES512;
use Jose\Component\Signature\Algorithm\None;
$algorithm_manager = AlgorithmManager::create([
new PS256(),
new ES512(),
new None(),
]);<?php
use Jose\Component\Core\AlgorithmManager;
use Jose\Component\Signature\Algorithm\PS256;
use Jose\Component\Signature\Algorithm\ES512;
$algorithm_manager = AlgorithmManager::create([
new PS256(),
new ES512(),
]);<?php
use Jose\Component\Core\AlgorithmManagerFactory;
use Jose\Component\Signature\Algorithm\PS256;
use Jose\Component\Encryption\Algorithm\KeyEncryption\PBES2HS512A256KW;
use Jose\Component\Encryption\Algorithm\ContentEncryption\A128CBCHS256;
$algorithm_manager_factory = new AlgorithmManagerFactory();
$algorithm_manager_factory
->add('PS256', new PS256())
->add('A128CBC-HS256', new A128CBCHS256())
->add('PBES2-HS512+A256KW', new PBES2HS512A256KW())
->add('PBES2-HS512+A256KW with custom configuration', new PBES2HS512A256KW(128, 8192))
;<?php
$signature_algorithm_manager = $algorithm_manager_factory->create(['PS256']);
$encryption_algorithm_manager = $algorithm_manager_factory->create(['A128CBC-HS256', 'PBES2-HS512+A256KW']);
$encryption_algorithm_manager_for_paranoid = $algorithm_manager_factory->create(['A128CBC-HS256', 'PBES2-HS512+A256KW with custom configuration']);services:
Jose\Component\Encryption\Algorithm\KeyEncryption\PBES2HS256A128KW:
arguments:
- 128 # salt size
- 10240 # counts
tags:
- {'name': 'jose.algorithm', 'alias': 'Ultra-Secured PBES2-HS256+A128KW'}$algorithmManager = $algorithmManagerFactory->create(['Ultra-Secured PBES2-HS256+A128KW']);<?php
use Jose\Component\Signature\JWSSerializerManagerFactory;
$jwsSerializerManagerFactory = $container->get(JWSSerializerManagerFactory::class);$jwsSerializerManager = $jwsSerializerManagerFactory->create(['jws_compact']);jose:
jws:
serializers:
serializer1:
serializers: ['jws_compact']
is_public: true<?php
$jwsSerializerManager = $container->get('jose.jws_serializer.serializer1');jose:
jws:
serializers:
serializer1:
serializers: ['jws_compact']
tags:
tag_name1: ~
tag_name2: {attribute1: 'foo'}composer require web-token/jwt-checker<?php
use Jose\Component\Checker\HeaderCheckerManager;
use Jose\Component\Checker\AlgorithmChecker;
use Jose\Component\Signature\JWSTokenSupport;
$headerCheckerManager = HeaderCheckerManager::create(
[
new AlgorithmChecker(['HS256']), // We check the header "alg" (algorithm)
],
[
new JWSTokenSupport(), // Adds JWS token type support
]
);$headerCheckerManager->check($jwt, 0);$headerCheckerManager->check($jwt, 0, ['alg', 'enc', 'crit']);<?php
use Jose\Component\Checker\HeaderCheckerManagerFactory;
use Jose\Component\Checker\AlgorithmChecker;
use Jose\Component\Encryption\JWETokenSupport;
use Jose\Component\Signature\JWSTokenSupport;
$headerCheckerManagerFactory = new HeaderCheckerManagerFactory();
$headerCheckerManagerFactory
->add('signature_alg', new AlgorithmChecker(['HS256']))
->add('key_encryption_alg', new AlgorithmChecker(['RSA1_5']))
->addTokenTypeSupport(new JWSTokenSupport())
->addTokenTypeSupport(new JWETokenSupport());
$headerCheckerManagerForSignatures = $headerCheckerManagerFactory->create(['signature_alg']);
$headerCheckerManagerForEncryption = $headerCheckerManagerFactory->create(['key_encryption_alg']);<?php
namespace Acme\Checker;
use Jose\Component\Checker\HeaderChecker;
use Jose\Component\Checker\InvalidHeaderException;
/**
* Class CustomChecker.
*/
final class CustomChecker implements HeaderChecker
{
public function checkHeader($value)
{
if (!is_array($value) || !in_array($value, ['foo', 'bar'])) {
throw new InvalidHeaderException('Invalid header "custom".', 'custom', $value);
}
}
// This header parameter name.
public function supportedHeader(): string
{
return 'custom';
}
// This method indicates if this parameter must be in the protected header or not.
public function protectedHeaderOnly(): bool
{
return true;
}
}composer require web-token/jwt-checkercomposer require web-token/jwt-checker<?php
use Jose\Component\Checker\HeaderCheckerManagerFactory;
use Jose\Component\Checker\ClaimCheckerManagerFactory;
$headerCheckerManagerFactory = $container->get(HeaderCheckerManagerFactory::class);
$headerCheckerManager = $headerCheckerManagerFactory->create([...]);
$claimCheckerManagerFactory = $container->get(ClaimCheckerManagerFactory::class);
$claimCheckerManager = $claimCheckerManagerFactory->create([...]);$jwsBuilder = $jwsBuilderFactory->create(['HS256']);$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();jose:
jws:
builders:
builder1:
signature_algorithms: ['HS256', 'RS256', 'ES256']
is_public: true$jws = $jwsBuilder
->create()
->withPayload('Hello World!')
->addSignature($jwk, ['alg' => 'HS256', 'b64' => false, 'crit' => ['b64']])
->build();composer require web-token/jwt-corejose.pharcurl -OL https://github.com/web-token/jwt-app/raw/gh-pages/jose.phar
curl -OL https://github.com/web-token/jwt-app/raw/gh-pages/jose.phar.pubkey./jose.phar<?php
use Jose\Component\Checker\ClaimCheckerManager;
use Jose\Component\Checker;
$claimCheckerManager = ClaimCheckerManager::create(
[
new Checker\IssuedAtChecker(),
new Checker\NotBeforeChecker(),
new Checker\ExpirationTimeChecker(),
new Checker\AudienceChecker('Audience'),
]
);use Jose\Component\Core\Converter\StandardConverter;
$jsonConverter = new StandardConverter();
$claims = $jsonConverter->decode($jwt->getPayload());
$claimCheckerManager->check($claims);$claimCheckerManager->check($claims, ['iss', 'sub', 'aud']);<?php
declare(strict_types=1);
namespace Acme\Checker;
use Jose\Component\Checker\ClaimChecker;
use Jose\Component\Checker\InvalidClaimException;
/**
* Class FooChecker.
*/
final class FooChecker implements ClaimCheckerInterface
{
/**
* {@inheritdoc}
*/
public function checkClaim($value)
{
if (!is_string($value)) { // If the value is not a string, then we throw an exception
throw new InvalidClaimException('The claim "foo" must be a string.', 'foo', $value);
}
if (!in_array($value, ['bar', 'bat'])) { // Check if the value is allowed
throw new InvalidClaimException('The claim "foo" must be "bar" or "bat".', 'foo', $value);
}
}
/**
* {@inheritdoc}
*/
public function supportedClaim(): string
{
return 'foo'; //The claim to check.
}
}<?php
use Jose\Component\Checker\ClaimCheckerManagerFactory;
use Jose\Component\Checker;
$claimCheckerManagerFactory = new ClaimCheckerManagerFactory();
$claimCheckerManagerFactory
->add('iat', new Checker\IssuedAtChecker())
->add('nbf', new Checker\NotBeforeChecker())
->add('exp', new Checker\ExpirationTimeChecker())
->add('aud1', new Checker\AudienceChecker('Audience for service #1'))
->add('aud2', new Checker\AudienceChecker('Audience for service #2'));
$claimCheckerManager1 = $claimCheckerManagerFactory->create(['iat', 'exp', 'aud2']);
$claimCheckerManager2 = $claimCheckerManagerFactory->create(['aud1', 'exp']);jose:
checkers:
claims:
checker1:
is_public: true
claims: [...]
headers:
checker1:
is_public: true
headers: [...]services
Acme\Checker\CustomHeaderChecker:
public: false
tags:
- { name: 'jose.checker.header', alias: 'foo' }
Acme\Checker\CustomClaimChecker:
public: false
tags:
- { name: 'jose.checker.claim', alias: 'bar' }jose:
checkers:
claims:
checker1:
claims: [...]
tags:
tag_name1: ~
tag_name2: {attribute1: 'foo'}<?php
$jwsBuilder = $container->get('jose.jws_builder.builder1');jose:
jws:
builders:
builder1:
signature_algorithms: ['HS256', 'RS256', 'ES256']
tags:
tag_name1: ~
tag_name2: {attribute1: 'foo'}<?php
use Jose\Component\Signature\JWSVerifierFactory;
$jwsVerifierFactory = $container->get(JWSVerifierFactory::class);$jwsVerifier = $jwsVerifierFactory->create(['HS256']);jose:
jws:
verifiers:
verifier1:
signature_algorithms: ['HS256', 'RS256', 'ES256']
is_public: true<?php
$jwsVerifier = $container->get('jose.jws_verifier.verifier1');jose:
jws:
verifiers:
verifier1:
signature_algorithms: ['HS256', 'RS256', 'ES256']
tags:
tag_name1: ~
tag_name2: {attribute1: 'foo'}<?php
use Jose\Component\Signature\JWSLoaderFactory;
$jwsLoaderFactory = $container->get(JWSLoaderFactory::class);jose:
jws:
loaders:
jws_loader1:
serializers: ['jws_compact']
signature_algorithms: ['HS256']
header_checkers: ['alg']
is_public: true<?php
use Jose\Bundle\JoseFramework\Helper\ConfigurationHelper;
...
ConfigurationHelper::addJWSLoader($container, 'jws_loader1', ['jws_compact'], ['HS256'], ['alg'], true);./jose.phar selfupdate./jose.phar rollback<?php
use Jose\Component\Encryption\JWEDecrypterFactory;
$jweDecrypterFactory = $container->get(JWEDecrypterFactory::class);$jweDecrypter = $jweDecrypterFactory->create(['HS256']);<?php
use Jose\Component\Encryption\JWEBuilderFactory;
$jweBuilderFactory = $container->get(JWEBuilderFactory::class);$jweBuilder = $jweBuilderFactory->create(
['A256GCMKW'],
['A256CBC-HS256'],
['DEF'] // Compression methods
);<?php
use Jose\Component\Encryption\JWESerializerManagerFactory;
$jweSerializerManagerFactory = $container->get(JWESerializerManagerFactory::class);$jweSerializerManager = $jweSerializerManagerFactory->create(['jwe_compact']);<?php
use Jose\Component\Core\AlgorithmManager;
use Jose\Component\Core\Converter\StandardConverter;
use Jose\Component\Encryption\Algorithm\KeyEncryption\A256KW;
use Jose\Component\Encryption\Algorithm\ContentEncryption\A256CBCHS512;
use Jose\Component\Encryption\Compression\CompressionMethodManager;
use Jose\Component\Encryption\Compression\Deflate;
use Jose\Component\Encryption\JWEBuilder;
// The key encryption algorithm manager with the A256KW algorithm.
$keyEncryptionAlgorithmManager = AlgorithmManager::create([
new A256KW(),
]);
// The content encryption algorithm manager with the A256CBC-HS256 algorithm.
$contentEncryptionAlgorithmManager = AlgorithmManager::create([
new A256CBCHS512(),
]);
// The compression method manager with the DEF (Deflate) method.
$compressionMethodManager = CompressionMethodManager::create([
new Deflate(),
]);
// The JSON Converter.
$jsonConverter = new StandardConverter();
// We instantiate our JWE Builder.
$jweBuilder = new JWEBuilder(
$jsonConverter,
$keyEncryptionAlgorithmManager,
$contentEncryptionAlgorithmManager,
$compressionMethodManager
);jose:
jwe:
decrypters:
decrypter1:
key_encryption_algorithms: ['A256GCMKW']
content_encryption_algorithms: ['A256CBC-HS256']
compression_methods: ['DEF']
is_public: true<?php
$jweDecrypter = $container->get('jose.jwe_decrypter.decrypter1');jose:
jwe:
decrypters:
decrypter1:
key_encryption_algorithms: ['A256GCMKW']
content_encryption_algorithms: ['A256CBC-HS256']
compression_methods: ['DEF']
tags:
tag_name1: ~
tag_name2: {attribute1: 'foo'}<?php
use Jose\Component\Encryption\JWELoaderFactory;
$jweLoaderFactory = $container->get(JWELoaderFactory::class);jose:
jwe:
loaders:
jwe_loader1:
key_encryption_algorithms: ['A256GCMKW']
content_encryption_algorithms: ['A256CBC-HS256']
compression_methods: ['DEF']
header_checkers: ['alg', 'enc']
is_public: true<?php
use Jose\Bundle\JoseFramework\Helper\ConfigurationHelper;
...
ConfigurationHelper::addJWELoader($container, 'jwe_loader1', ['jwe_compact'], ['A256GCMKW'], ['A256CBC-HS256'], ['DEF'], ['alg', 'enc'], true);jose:
jwe:
builders:
builder1:
key_encryption_algorithms: ['A256GCMKW']
content_encryption_algorithms: ['A256CBC-HS256']
compression_methods: ['DEF']
is_public: true<?php
$jweBuilder = $container->get('jose.jwe_builder.builder1');jose:
jwe:
builders:
builder1:
key_encryption_algorithms: ['A256GCMKW']
content_encryption_algorithms: ['A256CBC-HS256']
compression_methods: ['DEF']
tags:
tag_name1: ~
tag_name2: {attribute1: 'foo'}jose: # Configuration of the JWT Framework
keys: # Configuration of the keys
key_name: # Unique key name
method_name: # Name of the method
...
is_public: truejose:
keys:
key_name:
secret: # Method
secret: 'This is my shared secret'
additional_values:
use: 'sig'
alg: 'RS512'jose:
keys:
key_name:
jwk: # Method
value: '{"kty":"oct","k":"dzI6nbW4OcNF-AtfxGAmuyz7IpHRudBI0WgGjZWgaRJt6prBn3DARXgUR8NVwKhfL43QBIU2Un3AvCGCHRgY4TbEqhOi8-i98xxmCggNjde4oaW6wkJ2NgM3Ss9SOX9zS3lcVzdCMdum-RwVJ301kbin4UtGztuzJBeg5oVN00MGxjC2xWwyI0tgXVs-zJs5WlafCuGfX1HrVkIf5bvpE0MQCSjdJpSeVao6-RSTYDajZf7T88a2eVjeW31mMAg-jzAWfUrii61T_bYPJFOXW8kkRWoa1InLRdG6bKB9wQs9-VdXZP60Q4Yuj_WZ-lO7qV9AEFrUkkjpaDgZT86w2g"}'jose:
keys:
key_name:
certificate: # Method
path: '/path/to/your/X509/certificate'
additional_values: # Optional values
use: 'sig'
alg: 'RS256'jose:
keys:
key_name:
x5c: # Method
value: '-----BEGIN CERTIFICATE----- ....'
additional_values: # Optional values.
use: 'sig'
alg: 'RS256'jose:
keys:
key_name:
file: # Method
path: '/path/to/your/key/file'
password: 'secret' # Optional. Only if the key is encrypted
additional_values: # Optional values.
use: 'sig'
alg: 'RS256'jose:
keys:
key_name:
jwkset: # Method
key_set: 'jose.key_set.my_key_set' # JWKSet service
index: 0 # Use key at index 0jose:
jwe:
key_name:
jwk: # Method
value: '{"kty":"oct","k":"dzI6nbW4OcNF-AtfxGAmuyz7IpHRudBI0WgGjZWgaRJt6prBn3DARXgUR8NVwKhfL43QBIU2Un3AvCGCHRgY4TbEqhOi8-i98xxmCggNjde4oaW6wkJ2NgM3Ss9SOX9zS3lcVzdCMdum-RwVJ301kbin4UtGztuzJBeg5oVN00MGxjC2xWwyI0tgXVs-zJs5WlafCuGfX1HrVkIf5bvpE0MQCSjdJpSeVao6-RSTYDajZf7T88a2eVjeW31mMAg-jzAWfUrii61T_bYPJFOXW8kkRWoa1InLRdG6bKB9wQs9-VdXZP60Q4Yuj_WZ-lO7qV9AEFrUkkjpaDgZT86w2g"}'
tags:
tag_name1: ~
tag_name2: {attribute1: 'foo'}jose:
jwe:
serializers:
serializer1:
serializers: ['jwe_compact']
is_public: true<?php
$jweSerializerManager = $container->get('jose.jwe_serializer.serializer1');jose:
jwe:
serializers:
serializer1:
serializers: ['jwe_compact']
tags:
tag_name1: ~
tag_name2: {attribute1: 'foo'}/**
* {@inheritdoc}
*/
public function registerBundles()
{
$bundles = [
...
new Jose\Bundle\JoseFramework\JoseFrameworkBundle(),
];
return $bundles;
}use Jose\Component\Core\JWK;
// Our key.
$jwk = JWK::create([
'kty' => 'oct',
'k' => 'dzI6nbW4OcNF-AtfxGAmuyz7IpHRudBI0WgGjZWgaRJt6prBn3DARXgUR8NVwKhfL43QBIU2Un3AvCGCHRgY4TbEqhOi8-i98xxmCggNjde4oaW6wkJ2NgM3Ss9SOX9zS3lcVzdCMdum-RwVJ301kbin4UtGztuzJBeg5oVN00MGxjC2xWwyI0tgXVs-zJs5WlafCuGfX1HrVkIf5bvpE0MQCSjdJpSeVao6-RSTYDajZf7T88a2eVjeW31mMAg-jzAWfUrii61T_bYPJFOXW8kkRWoa1InLRdG6bKB9wQs9-VdXZP60Q4Yuj_WZ-lO7qV9AEFrUkkjpaDgZT86w2g',
]);
// The payload we want to encrypt. The payload MUST be a string hence we use our JSON Converter.
$payload = $jsonConverter->encode([
'iat' => time(),
'nbf' => time(),
'exp' => time() + 3600,
'iss' => 'My service',
'aud' => 'Your application',
]);
$jwe = $jweBuilder
->create() // We want to create a new JWE
->withPayload($payload) // We set the payload
->withSharedProtectedHeader([
'alg' => 'A256KW', // Key Encryption Algorithm
'enc' => 'A256CBC-HS512', // Content Encryption Algorithm
'zip' => 'DEF' // We enable the compression (irrelevant as the payload is small, just for the example).
])
->addRecipient($jwk) // We add a recipient (a shared key or public key).
->build(); // We build ituse Jose\Component\Encryption\Serializer\CompactSerializer;
$serializer = new CompactSerializer($jsonConverter); // The serializer
$token = $serializer->serialize($jwe, 0); // We serialize the recipient at index 0 (we only have one recipient).<?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
declare(strict_types=1);
namespace AcmeBundle\DependencyInjection;
use Jose\Bundle\JoseFramework\Helper\ConfigurationHelper;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
final class AcmeExtension extends Extension implements PrependExtensionInterface
{
...
/**
* {@inheritdoc}
*/
public function prepend(ContainerBuilder $container)
{
... // The Helper will be called here
}
}public static function addJWSVerifier(ContainerBuilder $container, string $name, array $signatureAlgorithms, bool $is_public = true, array $tags = [])<?php
// Check if the key has a parameter.
$jwk->has('kty');
// Retrieve the key parameter.
$jwk->get('kty');
// Retrieve all key parameters.
$jwk->all();
// Calculate the thumbprint of the key. Acceptable hash algorithms are those returned by the PHP function "hash_algos".
$jwk->thumbprint('sha256');
// If the key is a private key (RSA, EC, OKP), it can be converted into public:
$public_key = $jwk->toPublic();
// The JWK object can be serialized into JSON
json_encode($jwk);composer require web-token/jwt-key-mgmt<?php
use Jose\Component\KeyManagement\JWKFactory;
$key = JWKFactory::createOctKey(
1024, // Size in bits of the key. We recommend at least 128 bits.
[
'alg' => 'HS256', // This key must only be used with the HS256 algorithm
'use' => 'sig' // This key is used for signature/verification operations only
]
);<?php
use Jose\Component\KeyManagement\JWKFactory;
$jwk = JWKFactory::createFromSecret(
'My Secret Key', // The shared secret
[ // Optional additional members
'alg' => 'HS256',
'use' => 'sig'
]
);<?php
use Jose\Component\KeyManagement\JWKFactory;
$private_key = JWKFactory::createRSAKey(
4096, // Size in bits of the key. We recommend at least 2048 bits.
[
'alg' => 'RSA-OAEP-256', // This key must only be used with the RSA-OAEP-256 algorithm
'use' => 'enc' // This key is used for encryption/decryption operations only
]);<?php
use Jose\Component\KeyManagement\JWKFactory;
$key = JWKFactory::createECKey('P-256');<?php
use Jose\Component\KeyManagement\JWKFactory;
$key = JWKFactory::createOKPKey('X25519');<?php
use Jose\Component\KeyManagement\JWKFactory;
$key = JWKFactory::createNoneKey();<?php
use Jose\Component\KeyManagement\JWKFactory;
$key = JWKFactory::createFromValues([
'kid' => '71ee230371d19630bc17fb90ccf20ae632ad8cf8',
'kty' => 'RSA',
'alg' => 'RS256',
'use' => 'sig',
'n' => 'vnMTRCMvsS04M1yaKR112aB8RxOkWHFixZO68wCRlVLxK4ugckXVD_Ebcq-kms1T2XpoWntVfBuX40r2GvcD9UsTFt_MZlgd1xyGwGV6U_tfQUll5mKxCPjr60h83LXKJ_zmLXIqkV8tAoIg78a5VRWoms_0Bn09DKT3-RBWFjk=',
'e' => 'AQAB',
]);<?php
use Jose\Component\KeyManagement\JWKFactory;
$key = JWKFactory::createFromKeyFile(
'/path/to/my/key/file.pem', // The filename
'Secret', // Secret if the key is encrypted
[
'use' => 'sig', // Additional parameters
]
);<?php
use Jose\Component\KeyManagement\JWKFactory;
$key = JWKFactory::createFromPKCS12CertificateFile(
'/path/to/my/key/file.p12', // The filename
'Secret', // Secret if the key is encrypted
[
'use' => 'sig', // Additional parameters
]
);<?php
use Jose\Component\KeyManagement\JWKFactory;
$key = JWKFactory::createFromCertificateFile(
'/path/to/my/key/file.crt', // The filename
[
'use' => 'sig', // Additional parameters
]
);<?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);jose: # Configuration of the JWT Framework
key_sets: # Configuration of the keys
keyset_name: # Unique key name
method_name: # Name of the method
...
is_public: truejose:
key_sets:
key_name:
jwkset: # Method
value: '{"keys":[{"kty":"oct","k":"dzI6nbW4OcNF-AtfxGAmuyz7IpHRudBI0WgGjZWgaRJt6prBn3DARXgUR8NVwKhfL43QBIU2Un3AvCGCHRgY4TbEqhOi8-i98xxmCggNjde4oaW6wkJ2NgM3Ss9SOX9zS3lcVzdCMdum-RwVJ301kbin4UtGztuzJBeg5oVN00MGxjC2xWwyI0tgXVs-zJs5WlafCuGfX1HrVkIf5bvpE0MQCSjdJpSeVao6-RSTYDajZf7T88a2eVjeW31mMAg-jzAWfUrii61T_bYPJFOXW8kkRWoa1InLRdG6bKB9wQs9-VdXZP60Q4Yuj_WZ-lO7qV9AEFrUkkjpaDgZT86w2g"},{"kty":"oct","k":"bwIAv5Nn-fo8p4LCEvM4IR9eLXgzJRs8jXCLb3xR0tDJGiZ46KheO4ip6htFKyN2aqJqlNi9-7hB6I1aLLy1IRT9-vcBoCSGu977cNAUuRLkRp7vo8s6MsxhB8WvQBDRZghV7jIYaune-3vbE7iDU2AESr8BUtorckLoO9uW__fIabaa3hJMMQIHCzYQbJKZvlCRCKWMk2H_zuS4JeDFTvyZH1skJYF_TET1DrCZHMPicw-Yk3_m2P-ilC-yidPPoVzeU8Jj3tQ6gtX3975qiQW7pt2qbgjKAuq2wsz_9hxLBtMB5rQPafFoxop7O4BklvZ9-ECcK6dfI2CAx9_tjQ"}]}'httplug: # Example of client configuration
plugins:
cache: # We use the cache plugin
cache_pool: 'cache.app' # We use the PSR-6 Cache service of the application
config:
default_ttl: 1800 # TTL set to 30 min
clients:
acme:
factory: 'httplug.factory.guzzle6'
plugins: ['httplug.plugin.cache'] # We enable the cache plugin for that client.
jose:
jku_factory:
enabled: true
client: 'httplug.client.acme' # The Httplug client
request_factory: 'httplug.message_factory' # In general, you will use the same message factory as the one used by Httplugjose:
key_sets:
key_name:
jku: # Method
url: 'https://login.microsoftonline.com/common/discovery/keys'jose:
key_sets:
key_name:
x5u: # Method
url: 'https://www.googleapis.com/oauth2/v1/certs'jwkset_endpoints:
resource: "@JoseFrameworkBundle/Resources/config/routing/jwkset_controller.yml"jose:
key_sets:
public_keyset: # The key set we want to share
jwkset:
value: '{"keys":[{"kty":"OKP","crv":"X25519","x":"ovuZiVcMXBN4r0VgCvJy_ChAsBv4YPJGC5w56PzndXY"},{"kty":"OKP","crv":"X25519","x":"4qyOJ4T9RkdciIn6LDxb2LdM1Ov-dtBSuj0jh6nCuyc"}]}'
jwk_uris:
shared_keyset:
id: 'jose.key_set.public_keyset' # The key set service to share
path: '/certs' # Path of the key set. Final path is hostname/route_prefix/path: https://www.foo.com/keys/certs
max_age: 1000 # Set the HTTP cache max age of this key setjose:
key_sets:
key_name:
jku: # Method
url: 'https://login.microsoftonline.com/common/discovery/keys'
tags:
tag_name1: ~
tag_name2: {attribute1: 'foo'}<?php
use Jose\Component\Core\AlgorithmManager;
use Jose\Component\Encryption\Algorithm\KeyEncryption\A256KW;
use Jose\Component\Encryption\Algorithm\ContentEncryption\A256CBCHS512;
use Jose\Component\Encryption\Compression\CompressionMethodManager;
use Jose\Component\Encryption\Compression\Deflate;
use Jose\Component\Encryption\JWEDecrypter;
// The key encryption algorithm manager with the A256KW algorithm.
$keyEncryptionAlgorithmManager = AlgorithmManager::create([
new A256KW(),
]);
// The content encryption algorithm manager with the A256CBC-HS256 algorithm.
$contentEncryptionAlgorithmManager = AlgorithmManager::create([
new A256CBCHS512(),
]);
// The compression method manager with the DEF (Deflate) method.
$compressionMethodManager = CompressionMethodManager::create([
new Deflate(),
]);
// We instantiate our JWE Decrypter.
$jweDecrypter = new JWEDecrypter(
$keyEncryptionAlgorithmManager,
$contentEncryptionAlgorithmManager,
$compressionMethodManager
);<?php
use Jose\Component\Core\Converter\StandardConverter;
use Jose\Component\Core\JWK;
use Jose\Component\Encryption\Serializer\JWESerializerManager;
use Jose\Component\Encryption\Serializer\CompactSerializer;
// 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 JWE Compact Serialization Mode.
$serializerManager = JWESerializerManager::create([
new CompactSerializer($jsonConverter),
]);
// The input we want to decrypt
$token = 'eyJhbGciOiJBMjU2S1ciLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwiemlwIjoiREVGIn0.9RLpf3Gauf05QPNCMzPcH4XNBLmH0s3e-YWwOe57MTG844gnc-g2ywfXt_R0Q9qsR6WhkmQEhdLk2CBvfqr4ob4jFlvJK0yW.CCvfoTKO9tQlzCvbAuFAJg.PxrDlsbSRcxC5SuEJ84i9E9_R3tCyDQsEPTIllSCVxVcHiPOC2EdDlvUwYvznirYP6KMTdKMgLqxB4BwI3CWtys0fceSNxrEIu_uv1WhzJg.4DnyeLEAfB4I8Eq0UobnP8ymlX1UIfSSADaJCXr3RlU';
// We try to load the token.
$jwe = $serializerManager->unserialize($token);
// We decrypt the token. This method does NOT check the header.
$jwe = $jweDecrypter->decryptUsingKey($jwe, $jwk);<?php
use Jose\Component\Encryption\JWELoader;
$jweLoader = new JWELoader(
$serializerManager,
$jweDecrypter,
$headerCheckerManager
);
$jwe = $jweLoader->loadAndDecryptWithKey($token, $key, $recipient);<?php
use Jose\Component\Encryption\JWELoaderFactory;
$jweLoaderFactory = new JWELoaderFactory(
$jweSerializerManagerFactory,
$jweDecrypterFactory,
$headerCheckerManagerFactory
);
$jweLoader = $jweLoaderFactory->create(
['jwe_compact'], // List of serializer aliases
['A128KW'], // List of key encryption algorithm aliases
['A128KW'], // List of content encryption algorithm aliases
['DEF'], // List of compression method aliases
['alg', 'enc'] // Optional list of header checker aliases
);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, []);
}
}ConfigurationHelper::addKey(
$container,
'acme_my_key',
'jwk', [
'value' => '{"kty":"oct","k":"dzI6nbW4OcNF-AtfxGAmuyz7IpHRudBI0WgGjZWgaRJt6prBn3DARXgUR8NVwKhfL43QBIU2Un3AvCGCHRgY4TbEqhOi8-i98xxmCggNjde4oaW6wkJ2NgM3Ss9SOX9zS3lcVzdCMdum-RwVJ301kbin4UtGztuzJBeg5oVN00MGxjC2xWwyI0tgXVs-zJs5WlafCuGfX1HrVkIf5bvpE0MQCSjdJpSeVao6-RSTYDajZf7T88a2eVjeW31mMAg-jzAWfUrii61T_bYPJFOXW8kkRWoa1InLRdG6bKB9wQs9-VdXZP60Q4Yuj_WZ-lO7qV9AEFrUkkjpaDgZT86w2g"}',
'is_public' => true,
],
[
'tag_name1' => [],
'tag_name2' => ['attribute1' => 'foo'],
]
);jose:
keys:
acme_my_key:
jwk:
value: '{"kty":"oct","k":"dzI6nbW4OcNF-AtfxGAmuyz7IpHRudBI0WgGjZWgaRJt6prBn3DARXgUR8NVwKhfL43QBIU2Un3AvCGCHRgY4TbEqhOi8-i98xxmCggNjde4oaW6wkJ2NgM3Ss9SOX9zS3lcVzdCMdum-RwVJ301kbin4UtGztuzJBeg5oVN00MGxjC2xWwyI0tgXVs-zJs5WlafCuGfX1HrVkIf5bvpE0MQCSjdJpSeVao6-RSTYDajZf7T88a2eVjeW31mMAg-jzAWfUrii61T_bYPJFOXW8kkRWoa1InLRdG6bKB9wQs9-VdXZP60Q4Yuj_WZ-lO7qV9AEFrUkkjpaDgZT86w2g"}'
is_public: true
tags:
tag_name1: ~
tag_name2: {attribute1: 'foo'}<?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'.
}
}<?php
use Jose\Component\Core\AlgorithmManager;
use Jose\Component\Signature\Algorithm\HS256;
use Jose\Component\Signature\JWSVerifier;
// The algorithm manager with the HS256 algorithm.
$algorithmManager = AlgorithmManager::create([
new HS256(),
]);
// We instantiate our JWS Verifier.
$jwsVerifier = new JWSVerifier(
$algorithmManager
);<?php
use Jose\Component\Core\Converter\StandardConverter;
use Jose\Component\Core\JWK;
use Jose\Component\Signature\Serializer\JWSSerializerManager;
use Jose\Component\Signature\Serializer\CompactSerializer;
// 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),
]);
// The input we want to check
$token = 'eyJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1MDc4OTY5OTIsIm5iZiI6MTUwNzg5Njk5MiwiZXhwIjoxNTA3OTAwNTkyLCJpc3MiOiJNeSBzZXJ2aWNlIiwiYXVkIjoiWW91ciBhcHBsaWNhdGlvbiJ9.eycp9PTdgO4WA-68-AMoHPwsKDr68NhjIQKz4lUkiI0';
// We try to load the token.
$jws = $serializerManager->unserialize($token);
// We verify the signature. This method does NOT check the header.
// The arguments are:
// - The JWS object,
// - The key,
// - The index of the signature to check. See
$isVerified = $jwsVerifier->verifyWithKey($jws, $jwk, 0);<?php
use Jose\Component\Signature\JWSLoader;
$jwsLoader = new JWSLoader(
$serializerManager,
$jwsVerifier,
$headerCheckerManager
);
$jws = $jwsLoader->loadAndVerifyWithKey($token, $jwk, $signature, $payload);<?php
use Jose\Component\Signature\JWSLoaderFactory;
$jwsLoaderFactory = new JWSLoaderFactory(
$jwsSerializerManagerFactory,
$jwsVerifierFactory,
$headerCheckerManagerFactory
);
$jwsLoader = $jwsLoaderFactory->create(
['jws_compact'], // List of serializer aliases
['HS256'], // List of signature algorithm aliases
['alg'] // Optional list of header checker aliases
);<?php
use Jose\Component\Core\AlgorithmManager;
use Jose\Component\Encryption\Algorithm\KeyEncryption\A128KW;
use Jose\Component\Encryption\Algorithm\KeyEncryption\PBES2HS256A128KW;
use Jose\Component\Encryption\Algorithm\ContentEncryption\A128CBCHS256;
$algorithmManager = AlgorithmManager::create([
new A128KW(),
new PBES2HS256A128KW(),
new A128CBCHS256(),
]);<?php
use Jose\Component\Core\AlgorithmManager;
use Jose\Component\Encryption\Algorithm\KeyEncryption\PBES2HS256A128KW;
$algorithmManager = AlgorithmManager::create([
new PBES2HS256A128KW(16, 1024),
]);ECDH-ES+A128KW (class ECDHESA128KW) READ THE NOTE BELOWPBES2-HS384+A192KW (class PBES2HS384A192KW)RSA-OAEP (class RSAOAEP)A192CBC-HS384 (class A192CBCHS384)<?php
use Jose\Factory\JWKFactory;
use Jose\Factory\JWSFactory;
$header = [
'alg' => 'RS256',
];
$jws = JWSFactory::createJWSToCompactJSON(
$claims, // The payload
$key, // The private/shared key used to sign
$header // The token protected header
);<?php
use Jose\Factory\JWEFactory;
use Jose\Factory\JWKFactory;
// We want to encrypt a very important message
$message = 'Today, 8:00PM, train station.';
$jwe = JWEFactory::createJWEToCompactJSON(
$message, // The message to encrypt
$key, // The key of the recipient
[ // The shared protected header
'alg' => 'RSA-OAEP-256',
'enc' => 'A256CBC-HS512',
'zip' => 'DEF',
]
);<?php
use Jose\Component\Core\AlgorithmManager;
use Jose\Component\Core\Converter\StandardConverter;
use Jose\Component\Signature\JWSBuilder;
use Jose\Component\Signature\Algorithm\RS256;
use Jose\Component\Signature\Serializer\CompactSerializer;
// This converter wraps json_encode/json_decode with some parameters
$jsonConverter = new StandardConverter();
// This managers handles all algorithms we need to use.
$algorithmManager = AlgorithmManager::create([
new RS256(),
]);
// The JWS Builder
$jwsBuilder = new JWSBuilder($jsonConverter, $algorithmManager);
// First we have to encode the payload. Now only strings are accepted.
$payload = $jsonConverter->encode($claims);
// We build our JWS object
$jws = $jwsBuilder
->create() // Indicates we want to create a new token
->withPayload($payload) // We set the payload
->addSignature($key, $header) // We add a signature
->build(); // We compute the JWS
// We need to serialize the token.
// In this example we will use the compact serialization mode (most common mode).
$serializer = new CompactSerializer($jsonConverter);
$token = $serializer->serialize($jws);<?php
use Jose\Checker\AudienceChecker;
use Jose\Factory\CheckerManagerFactory;
use Jose\Loader;
// The loader
$loader = new Loader();
// We load and verify the input
$jws = $loader->loadAndVerifySignatureUsingKey(
$input,
$key,
['RS256'],
$signature_index
);
// We prepare the claim/header checker
$checker = CheckerManagerFactory::createClaimCheckerManager(
['iat', 'nbf'], // We should enable 'exp', but this example will fail as the token has already expired
['crit']
);
// We check the token
$checker->checkJWS($jws, 0);<?php
use Jose\Component\Core\AlgorithmManager;
use Jose\Component\Core\Converter\StandardConverter;
use Jose\Component\Checker\ClaimCheckerManager;
use Jose\Component\Checker\HeaderCheckerManager;
use Jose\Component\Checker\AlgorithmChecker;
use Jose\Component\Checker\ExpirationTimeChecker;
use Jose\Component\Signature\JWSVerifier;
use Jose\Component\Signature\Algorithm\RS256;
use Jose\Component\Signature\Serializer\CompactSerializer;
use Jose\Component\Signature\JWSTokenSupport;
$jsonConverter = new StandardConverter();
$serializer = new CompactSerializer($jsonConverter);
$jws = $serializer->unserialize($input);
$headerChecker = HeaderCheckerManager::create(
[new AlgorithmChecker(['RS256'])], // A list of header checkers
[new JWSTokenSupport()] // A list of token support services (we only use the JWS token type here)
);
$algorithmManager = AlgorithmManager::create([
new RS256(),
]);
$jwsVerifier = new JWSVerifier($algorithmManager);
$claimChecker = ClaimCheckerManager::create(
[new ExpirationTimeChecker()] // A list of claim checkers
);
// We check all signatures
$isVerified = false;
for ($i = 0; $i < $jws->count(); $i++) {
try {
$headerChecker->check($jws, 0); // We check the header of the first (index=0) signature.
if ($jwsVerifier->verifyWithKey($jws, $key, 0)) { // We verify the signature
$isVerified = true;
break;
}
} catch (\Exception $e) {
continue;
}
}
if (!$isVerified) {
//Unable to check the token. The header or the signature verification failed.
} else {
// We check the claims.
// If everything is ok, claims can be used.
$claims = $jsonConverter->decode($jws->getPayload());
$claimChecker->check($claims); // We check the claims.
}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);<?php
use Jose\Component\Core\AlgorithmManager;
use Jose\Component\Core\Converter\StandardConverter;
use Jose\Component\Encryption\Algorithm\KeyEncryption\RSAOAEP256;
use Jose\Component\Encryption\Algorithm\ContentEncryption\A256CBCHS512;
use Jose\Component\Encryption\Compression\CompressionMethodManager;
use Jose\Component\Encryption\Compression\Deflate;
use Jose\Component\Encryption\JWEBuilder;
use Jose\Component\Encryption\Serializer\CompactSerializer;
$keyEncryptionAlgorithmManager = AlgorithmManager::create([
new RSAOAEP256(),
]);
$contentEncryptionAlgorithmManager = AlgorithmManager::create([
new A256CBCHS512(),
]);
$compressionMethodManager = CompressionMethodManager::create([
new Deflate(),
]);
$jsonConverter = new StandardConverter();
$jweBuilder = new JWEBuilder(
$jsonConverter,
$keyEncryptionAlgorithmManager,
$contentEncryptionAlgorithmManager,
$compressionMethodManager
);
$message = 'Today, 8:00PM, train station.';
$jwe = $jweBuilder
->create()
->withPayload($message)
->withSharedProtectedHeader([
'alg' => 'RSA-OAEP-256',
'enc' => 'A256CBC-HS512',
'zip' => 'DEF'
])
->addRecipient($jwk)
->build();
$serializer = new CompactSerializer($jsonConverter);
$token = $serializer->serialize($jwe, 0);<?php
use Jose\Factory\JWKFactory;
use Jose\Loader;
// We create our loader.
$loader = new Loader();
// This is the input we want to load verify.
$input = 'eyJhbGciOiJSU0EtT0FFUCIsImtpZCI6InNhbXdpc2UuZ2FtZ2VlQGhvYmJpdG9uLmV4YW1wbGUiLCJlbmMiOiJBMjU2R0NNIn0.rT99rwrBTbTI7IJM8fU3Eli7226HEB7IchCxNuh7lCiud48LxeolRdtFF4nzQibeYOl5S_PJsAXZwSXtDePz9hk-BbtsTBqC2UsPOdwjC9NhNupNNu9uHIVftDyucvI6hvALeZ6OGnhNV4v1zx2k7O1D89mAzfw-_kT3tkuorpDU-CpBENfIHX1Q58-Aad3FzMuo3Fn9buEP2yXakLXYa15BUXQsupM4A1GD4_H4Bd7V3u9h8Gkg8BpxKdUV9ScfJQTcYm6eJEBz3aSwIaK4T3-dwWpuBOhROQXBosJzS1asnuHtVMt2pKIIfux5BC6huIvmY7kzV7W7aIUrpYm_3H4zYvyMeq5pGqFmW2k8zpO878TRlZx7pZfPYDSXZyS0CfKKkMozT_qiCwZTSz4duYnt8hS4Z9sGthXn9uDqd6wycMagnQfOTs_lycTWmY-aqWVDKhjYNRf03NiwRtb5BE-tOdFwCASQj3uuAgPGrO2AWBe38UjQb0lvXn1SpyvYZ3WFc7WOJYaTa7A8DRn6MC6T-xDmMuxC0G7S2rscw5lQQU06MvZTlFOt0UvfuKBa03cxA_nIBIhLMjY2kOTxQMmpDPTr6Cbo8aKaOnx6ASE5Jx9paBpnNmOOKH35j_QlrQhDWUN6A2Gg8iFayJ69xDEdHAVCGRzN3woEI2ozDRs.-nBoKLH0YkLZPSI9.o4k2cnGN8rSSw3IDo1YuySkqeS_t2m1GXklSgqBdpACm6UJuJowOHC5ytjqYgRL-I-soPlwqMUf4UgRWWeaOGNw6vGW-xyM01lTYxrXfVzIIaRdhYtEMRBvBWbEwP7ua1DRfvaOjgZv6Ifa3brcAM64d8p5lhhNcizPersuhw5f-pGYzseva-TUaL8iWnctc-sSwy7SQmRkfhDjwbz0fz6kFovEgj64X1I5s7E6GLp5fnbYGLa1QUiML7Cc2GxgvI7zqWo0YIEc7aCflLG1-8BboVWFdZKLK9vNoycrYHumwzKluLWEbSVmaPpOslY2n525DxDfWaVFUfKQxMF56vn4B9QMpWAbnypNimbM8zVOw.UCGiqJxhBI3IFVdPalHHvA';
// The payload is decrypted using our key.
$jwe = $loader->loadAndDecryptUsingKey(
$input, // The input to load and decrypt
$jwk, // The symmetric or private key
['RSA-OAEP'], // A list of allowed key encryption algorithms
['A256GCM'], // A list of allowed content encryption algorithms
$recipient_index // If decrypted, this variable will be set with the recipient index used to decrypt
);<?php
use Jose\Component\Core\AlgorithmManager;
use Jose\Component\Core\Converter\StandardConverter;
use Jose\Component\Encryption\Algorithm\KeyEncryption\RSAOAEP256;
use Jose\Component\Encryption\Algorithm\ContentEncryption\A256CBCHS512;
use Jose\Component\Encryption\Compression\CompressionMethodManager;
use Jose\Component\Encryption\Compression\Deflate;
use Jose\Component\Encryption\JWEBuilder;
use Jose\Component\Encryption\Serializer\CompactSerializer;
use Jose\Component\Encryption\Serializer\JWESerializerManager;
$keyEncryptionAlgorithmManager = AlgorithmManager::create([
new RSAOAEP256(),
]);
$contentEncryptionAlgorithmManager = AlgorithmManager::create([
new A256CBCHS512(),
]);
$compressionMethodManager = CompressionMethodManager::create([
new Deflate(),
]);
$jsonConverter = new StandardConverter();
$jweBuilder = new JWEBuilder(
$jsonConverter,
$keyEncryptionAlgorithmManager,
$contentEncryptionAlgorithmManager,
$compressionMethodManager
);
$serializerManager = JWESerializerManager::create([
new CompactSerializer($jsonConverter),
]);
$token = 'eyJhbGciOiJBMjU2S1ciLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwiemlwIjoiREVGIn0.9RLpf3Gauf05QPNCMzPcH4XNBLmH0s3e-YWwOe57MTG844gnc-g2ywfXt_R0Q9qsR6WhkmQEhdLk2CBvfqr4ob4jFlvJK0yW.CCvfoTKO9tQlzCvbAuFAJg.PxrDlsbSRcxC5SuEJ84i9E9_R3tCyDQsEPTIllSCVxVcHiPOC2EdDlvUwYvznirYP6KMTdKMgLqxB4BwI3CWtys0fceSNxrEIu_uv1WhzJg.4DnyeLEAfB4I8Eq0UobnP8ymlX1UIfSSADaJCXr3RlU';
$jwe = $serializerManager->unserialize($token);
$jwe = $jweDecrypter->decryptUsingKey($jwe, $jwk);./vendor/bin/phpbench run --store./vendor/bin/phpbench run --group GROUP --store./vendor/bin/phpbench run --group hmac --store./vendor/bin/phpbench run --group RSA1_5 --storePhpBench 0.13.0. Running benchmarks.
Using configuration file: phpbench.json
............
12 subjects, 12 iterations, 12,000 revs, 0 rejects
(best [mean mode] worst) = 31.275 [86.783 86.783] 31.275 (μs)
⅀T: 1,041.395μs μSD/r 0.000μs μRSD/r: 0.000%
Storing results ... OK
Run: 133c8a853cf321f0b7b63e4e60f819f9910e1285./vendor/bin/phpbench report --report=simple --output=md --uuid=133c8a853cf321f0b7b63e4e60f819f9910e1285Jose Performance Test Suite
===========================
### suite: 133c8a853cf321f0b7b63e4e60f819f9910e1285, date: 2017-09-20, stime: 22:05:45
benchmark | groups | subject | mean
--- | --- | --- | ---
HS256Bench | JWS,hmac,HS256 | benchSignature | 104.450μs
HS256Bench | JWS,hmac,HS256 | benchVerification | 161.093μs
HS384Bench | JWS,hmac,HS384 | benchSignature | 112.788μs
HS384Bench | JWS,hmac,HS384 | benchVerification | 161.978μs
HS512Bench | JWS,hmac,HS512 | benchSignature | 105.686μs
HS512Bench | JWS,hmac,HS512 | benchVerification | 163.139μs./vendor/bin/phpbench report --report=default --output=md --uuid=133c8a853cf321f0b7b63e4e60f819f9910e1285A128KWA128CBC-HS256, A192CBC-HS384 and A256CBC-HS512./jose.phar key:convert:public '{"kty":"EC","crv":"P-256","d":"kiNCxSbRjlAbHrEbrwVKS8vIXUh6URChrmw","x":"-wdLWDWCZP6oFYl8aGVfU0MsFlckjaSVrO7hEsc8lgk","y":"rt8XDTalLMCRB5Tu9WQc2d0TOVwXXHkVDbI7cIig6r4"}'
{"kty":"EC","crv":"P-256","x":"-wdLWDWCZP6oFYl8aGVfU0MsFlckjaSVrO7hEsc8lgk","y":"rt8XDTalLMCRB5Tu9WQc2d0TOVwXXHkVDbI7cIig6r4"}./jose.phar key:analyze '{"kty":"oct","k":"N2aIJSQCxTo"}'
The parameter "alg" should be added.
The parameter "use" should be added.
The parameter "kid" should be added.
The key length is less than 128 bits../jose.phar key:convert:pkcs1 '{"kty":"EC","crv":"P-256","d":"kiNCxSbRjlAbHrEbrwVKS8vIXUh6URChrmw","x":"-wdLWDWCZP6oFYl8aGVfU0MsFlckjaSVrO7hEsc8lgk","y":"rt8XDTalLMCRB5Tu9WQc2d0TOVwXXHkVDbI7cIig6r4"}'
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIJIjQsUm0Y5QGx6xG68N4GrprVrFSkvLyF1IelEQoa5soAoGCCqGSM49
AwEHoUQDQgAE+wdLWDWCZP6oFYl8aGVfU0MsFlckjaSVrO7hEsc8lgmu3xcNNqUs
wJEHlO71ZBzZ3RM5XBdceRUNsjtwiKDqvg==
-----END EC PRIVATE KEY-----./jose.phar key:generate:ec P-256
{"kty":"EC","crv":"P-256","d":"BZ231BFhhHAhx-D4myu4O1hi-vUHnRqxoCsQKUKFNrA","x":"Tv5YeQuD1CWDbfre65kYX2Lq_MGnUq0Ek2yUFixy31M","y":"pj0FyoGaByyBlt5RbTHhBdgcC-S6cgxzLpxd6mGmsbM"}./jose.phar key:generate:rsa 512
{"kty":"RSA","n":"l1UPHqgOFThDUlfrP2DFnCwsD5ITls12nXer6A4YepUP_DnF9mFoXCkyflA_TOJtFiZW6NXWOY0NdE3YjzT-qQ","e":"AQAB","d":"CxVvxg8I-QTl6WIHGN09m_KgR4Ora6Agz-ez74sYv-GONPD3yjEWeAavdOsGK8iJX4Pe1Qss52VKddeKRQ9LAQ","p":"xkR0kbThGGD8HYtfPUv5Ds1zE5LlQvYgBiv15eOk9ns","q":"w2Xk86kiaRhXWXM8XPJ5Tn6bdTT6thzoqazuIO53SCs","dp":"RCBLibGEUvMoTiKQtChByRNRQl2MR2j48gXy9W42Rbc","dq":"T0x5910LxwUG5hl7ROluy6lcI9wFZ4Uh80JoPdspc5M","qi":"Z73ha9Fmg6s-rgRbF0dG0QMd1aY9g1i8qnAxXp3JMus"}./jose.phar key:generate:oct 256
{"kty":"oct","k":"kWpZXidz3sVVx2Jn1J-5ANXnA2IKwfIAY2CoBW1q7I0"}./jose.phar key:generate:okp 256
{"kty":"OKP","crv":"X25519","x":"TgTD7RS0KF3eU8HdTM6ACxu365uco3x2Cee9SBXiu2I","d":"BypCXV7KUai-zrwrdoAmgnHX6Kosw0sVpDVPwrXoNKY"}./jose.phar key:generate:none
{"kty":"none","use":"sig","alg":"none"}./jose.phar key:generate:from_secret "This is my secret"./jose.phar key:generate:from_secret "VGhpcyBpcyBteSBzZWNyZXQ=" --is_b64./jose.phar key:load:key /path/to/file.pem "This is my secret to decrypt the key"
{"kty":"OKP","crv":"X25519","x":"TgTD7RS0KF3eU8HdTM6ACxu365uco3x2Cee9SBXiu2I","d":"BypCXV7KUai-zrwrdoAmgnHX6Kosw0sVpDVPwrXoNKY"}./jose.phar key:load:p12 /path/to/file.p12 "This is my secret to decrypt the key"
{"kty":"OKP","crv":"X25519","x":"TgTD7RS0KF3eU8HdTM6ACxu365uco3x2Cee9SBXiu2I","d":"BypCXV7KUai-zrwrdoAmgnHX6Kosw0sVpDVPwrXoNKY"}./jose.phar key:load:x509 /path/to/file.cert
{"kty":"OKP","crv":"X25519","x":"TgTD7RS0KF3eU8HdTM6ACxu365uco3x2Cee9SBXiu2I"}./jose.phar key:optimize '{"kty":"RSA","n":"l4mLzvr6ewIWrPvP6j5PYp0yPRhtkMW1F-dbQ1VWGoB_Mq5IIuflOo7W2ERyh71exUGkmvoesWL3zCtFIOnlxw","e":"AQAB","d":"lxh8oLq7el9QwNasL0JF4WwgJa7vwISB1v3Gj9LM8cpZPqXnPGPeoE5QAOUi1bJsIEqzHsR-rnLHsarlTfXMIQ"}'
{"kty":"RSA","n":"l4mLzvr6ewIWrPvP6j5PYp0yPRhtkMW1F-dbQ1VWGoB_Mq5IIuflOo7W2ERyh71exUGkmvoesWL3zCtFIOnlxw","e":"AQAB","d":"lxh8oLq7el9QwNasL0JF4WwgJa7vwISB1v3Gj9LM8cpZPqXnPGPeoE5QAOUi1bJsIEqzHsR-rnLHsarlTfXMIQ","p":"w0WuNlrO16rSPKHQn02FsOwzczlchC9ZpdS-00JKOr8","q":"xqn5LMfXwhWK-RGlXkSUHKCPb-SLKV8f8p41pDkjvvk","dp":"NGGAtfvt-FROSQ1vFQyKjEcQFhyRALRi6-UBu1HQ76k","dq":"kUqaO4_kUcNjogivwqOxFsauYIzq4dT6Dnx6iqJnbDE","qi":"TwJ4WOG0r1q6vZ13Kze2HPXtlnllyq9ZfClrVwovC_I"}./jose.phar key:thumbprint '{"kty":"RSA","n":"l4mLzvr6ewIWrPvP6j5PYp0yPRhtkMW1F-dbQ1VWGoB_Mq5IIuflOo7W2ERyh71exUGkmvoesWL3zCtFIOnlxw","e":"AQAB","d":"lxh8oLq7el9QwNasL0JF4WwgJa7vwISB1v3Gj9LM8cpZPqXnPGPeoE5QAOUi1bJsIEqzHsR-rnLHsarlTfXMIQ","p":"xqn5LMfXwhWK-RGlXkSUHKCPb-SLKV8f8p41pDkjvvk","q":"w0WuNlrO16rSPKHQn02FsOwzczlchC9ZpdS-00JKOr8","dp":"kUqaO4_kUcNjogivwqOxFsauYIzq4dT6Dnx6iqJnbDE","dq":"NGGAtfvt-FROSQ1vFQyKjEcQFhyRALRi6-UBu1HQ76k","qi":"dkguRXkQcrvYbvFcnmGrcjIs36FJa-1dtd7QCRYHTBo"}'
gNur2UtA8NMAoxJfgMYhJqnuWR8u-60aeRbKtZwj4DE./jose.phar keyset:convert:public '<keyset here>'
<public keyset>./jose.phar keyset:analyze '<keyset here>'
<keyset analyze result>./jose.phar keyset:generate:rsa 3 512 # Create 3 RSA keys (512 bits each)
./jose.phar keyset:generate:oct 5 128 # Create 5 oct keys (128 bits each)
./jose.phar keyset:generate:okp 2 X25519 # Create 2 OKP keys (curve X25519)
./jose.phar keyset:generate:ec 3 P-521 # Create 3 EC keys (curve P-521)prependKeykid or custom parameter).php-http/httplug-bundle and (I will use php-http/guzzle6-adapter here)<?php
use Jose\Object\JWKSet;
$keyset = new JWKSet(['keys' => [
'71ee230371d19630bc17fb90ccf20ae632ad8cf8' => [
'kid' => '71ee230371d19630bc17fb90ccf20ae632ad8cf8',
'kty' => 'RSA',
'alg' => 'RS256',
'use' => 'sig',
'n' => 'vnMTRCMvsS04M1yaKR112aB8RxOkWHFixZO68wCRlVLxK4ugckXVD_Ebcq-kms1T2XpoWntVfBuX40r2GvcD9UsTFt_MZlgd1xyGwGV6U_tfQUll5mKxCPjr60h83LXKJ_zmLXIqkV8tAoIg78a5VRWoms_0Bn09DKT3-RBWFjk=',
'e' => 'AQAB',
]]]);
json_encode($keyset); // The key as a Json object
$keyset->addKey(new JWK(['kty' => 'none'])); // Add a key
$keyset->removeKey(1); // Remove a key
$keyset->prependKey(new JWK(['kty' => 'none'])); // Prepend a key
$keyset[0]; // Access keys like arrays do
foreach ($keyset as $key) { // Iterate on a key set
...
}<?php
use Jose\Component\Core\JWKSet;
// Create using direct values
$keyset = JWKSet::createFromKeyData(['keys' => [
'71ee230371d19630bc17fb90ccf20ae632ad8cf8' => [
'kid' => '71ee230371d19630bc17fb90ccf20ae632ad8cf8',
'kty' => 'RSA',
'alg' => 'RS256',
'use' => 'sig',
'n' => 'vnMTRCMvsS04M1yaKR112aB8RxOkWHFixZO68wCRlVLxK4ugckXVD_Ebcq-kms1T2XpoWntVfBuX40r2GvcD9UsTFt_MZlgd1xyGwGV6U_tfQUll5mKxCPjr60h83LXKJ_zmLXIqkV8tAoIg78a5VRWoms_0Bn09DKT3-RBWFjk=',
'e' => 'AQAB',
]]]);
// Create using a list of JWK objects
$keyset = JWKSet::createFromKeys([
JWK::create(['kty' => 'none']),
]);
// Create from a JWKSet as a Json object
$keyset = JWKSet::createFromJson('{"keys":{"71ee230371d19630bc17fb90ccf20ae632ad8cf8":{"kid":"71ee230371d19630bc17fb90ccf20ae632ad8cf8","kty":"RSA","alg":"RS256","use":"sig","n":"vnMTRCMvsS04M1yaKR112aB8RxOkW...9DKT3-RBWFjk=","e":"AQAB"}}}');
$keyset->has('71ee230371d19630bc17fb90ccf20ae632ad8cf8'); // Indicates if a key with a key ID (string) or index (integer) is in the key set.
$keyset->get('71ee230371d19630bc17fb90ccf20ae632ad8cf8'); // Retrieve a key with a key ID (string) or index (integer).
$keyset->count(); // Number of keys in the key set.
count($keyset); // Number of keys in the key set.
$keyset->all(); // An array of keys.
$newKeyset = $keyset->with(JWK::create(['kty' => 'none'])); // Adds a key in the key set. The returned key set is a new object (immutability).
$newKeyset = $keyset->without(0); // Removes a key from the key set. The returned key set is a new object (immutability).
$keyset->selectKey('sig', new RS256(), ['kid' => '71ee230371d19630bc17fb90ccf20ae632ad8cf8']);parameters:
private_key_set: '%env(jwkset:PRIVATE_KEY_SET)'
signature_key: '%env(jwk:SIGNATURE_KEY)'$container->getParameter('private_key_set'); // Will return a JWKSet object<?php
declare(strict_types=1);
namespace AppBundle\Service;
use Jose\Component\Core\JWKSet;
final class Foo
{
public function __construct(JWKSet $jwkset)
{
...
}
}services:
AppBundle\Service\Foo:
arguments:
- '%private_key_set%'<?php
use Jose\Factory\JWKFactory;
$jwkset = JWKFactory::createFromJKU('https://www.googleapis.com/oauth2/v3/certs');new Http\HttplugBundle\HttplugBundle(),
new Jose\Bundle\JoseFramework\JoseFrameworkBundle(),<?php
# app/AppBundle/Service/RequestFactory.php
namespace AppBundle\Service;
use GuzzleHttp\Psr7\Request;
use Http\Message\RequestFactory as Psr7RequestFactory;
final class RequestFactory implements Psr7RequestFactory
{
/**
* {@inheritdoc}
*/
public function createRequest($method, $uri, array $headers = [], $body = null, $protocolVersion = '1.1')
{
return new Request($method, $uri, $headers, $body, $protocolVersion);
}
}services:
AppBundle\Service\RequestFactory: ~jose:
jku_factory:
enabled: true # We enable the JKU factory
client: 'httplug.client.my_client' # We indicate the Httplug client to use
request_factory: 'AppBundle\Service\RequestFactory' # See hereafter the corresponding class
httplug:
plugins:
cache: # We use the cache plugin
cache_pool: 'cache.app' # We use the PSR-6 Cache service of the application
config:
default_ttl: 1800 # TTL set to 30 min
clients:
my_client: # Our client based on Guzzle 6. The corresponding service will be `httplug.client.my_client`
factory: 'httplug.factory.guzzle6'
plugins: ['httplug.plugin.cache'] # We enable the cache plugin for that clientuse Jose\Component\Core\JWKSet;
use Jose\Component\KeyManagement\JKUFactory;
class MyClass
{
private $jkuFactory;
public function __construct(JKUFactory $jkuFactory)
{
$this->client = $client;
$this->jkuFactory= $jkuFactory;
}
public function getKeySet(): JWKSet
{
return $this->jkuFactory->loadFromUrl($url);
}
}jose:
keys:
microsoft_keys:
jku:
url: 'https://login.microsoftonline.com/common/discovery/keys'$jweBuilder
->create()
->withPayload('...')
->withSharedProtectedHeader(['enc' => 'A128GCM'])
->addRecipient($recipient_key_1, ['alg' => 'RSA1_5'])
->addRecipient($recipient_key_2, ['alg' => 'RSA-OAEP-256'])
->build();