To perform cryptographic operations (signature/verification and encryption/decryption), you will also need keys.
The JWK object is part of the web-token/jwt-core component:
composer require web-token/jwt-coreA JWK object represents a key. It contains all parameters needed by the algorithm and may also provide information parameters.
This framework is able to create private and public keys easily. It can also generate those keys from external resources such as binary key files or certificates.
The keys can be grouped in key sets. A JWKSet object represents a key set. It can contain as many keys as you need.
We strongly recommend you to avoid mixing public, private or shared keys in the same key set.
You can create a JWK object using two static methods:
new JWK(array $values): creates a JWK using direct values.
JWK::createFromJson(string $json): creates a JWK using a JSON object.
Hereafter all methods available for a JWK object. The variable $jwk is a valid JWK object.
Please note a JWK object is an immutable object. If you change a value using a setter, it will return a new object.
<?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);This framework is able to create private and public keys on the fly using the JWKFactory. It is available in the web-token/jwt-key-mgmt component.
composer require web-token/jwt-key-mgmt4 types of keys are supported:
Symmetric Key:
oct: octet string
Asymmetric Key:
RSA: RSA key pair
EC : Elliptic Curve key pair
OKP: Octet key pair
The following example will show you how to create an oct key.
Additional parameters will be set to limit the scope of this key (e.g. signature/verification only with the HS256 algorithm).
<?php
use Jose\Component\KeyManagement\JWKFactory;
$key = JWKFactory::createOctKey(
1024, // Size in bits of the key. Should be at least of the same size as the hashing algorithm.
[
'alg' => 'HS256', // This key must only be used with the HS256 algorithm
'use' => 'sig' // This key is used for signature/verification operations only
]
);If you already have a shared secret, you can use it to create an oct key:
<?php
use Jose\Component\KeyManagement\JWKFactory;
$jwk = JWKFactory::createFromSecret(
'My Secret Key', // The shared secret
[ // Optional additional members
'alg' => 'HS256',
'use' => 'sig'
]
);The following example will show you how to create a RSA key.
The key size must be of 384 bits at least, but nowadays the recommended size is 2048 bits.
<?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
]);The following example will show you how to create a EC key.
<?php
use Jose\Component\KeyManagement\JWKFactory;
$key = JWKFactory::createECKey('P-256');The supported curves are:
P-256
P-384
P-521 (note that this is 521 and not 512)
The following example will show you how to create a OKP key.
<?php
use Jose\Component\KeyManagement\JWKFactory;
$key = JWKFactory::createOKPKey('X25519');The supported curves are:
Ed25519 for signature/verification only
X25519 for encryption/decryption only
The none key type is a special type used only for the none algorithm.
<?php
use Jose\Component\KeyManagement\JWKFactory;
$key = JWKFactory::createNoneKey();In case you already have key values, you can create a key by passing those values as an argument:
<?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',
]);You can convert a PKCS#1 or PKCS#8 key file into a JWK. The following method supports PEM and DER formats. Encrypted keys are also supported.
<?php
use Jose\Component\KeyManagement\JWKFactory;
$key = JWKFactory::createFromKeyFile(
'/path/to/my/key/file.pem', // The filename
'Secret', // Secret if the key is encrypted, otherwise null
[
'use' => 'sig', // Additional parameters
]
);You can convert a PKCS#12 Certificate into a JWK. Encrypted certificates are also supported.
<?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
]
);You can convert a X.509 Certificate into a JWK.
<?php
use Jose\Component\KeyManagement\JWKFactory;
$key = JWKFactory::createFromCertificateFile(
'/path/to/my/key/file.crt', // The filename
[
'use' => 'sig', // Additional parameters
]
);You can create a JWKSet object using three static methods:
new JWKSet(array $keys): creates a JWKSet using a list of JWK objects.
JWKSet::createFromJson(string $json): creates a JWKSet using a JSON object.
JWKSet::createFromKeyData(array $values): creates a JWKSet using a decoded JSON object.
Hereafter all methods available for a JWKSet object. The variable $jwkset is a valid JWKSet object.
Please note a JWKSet object is an immutable object. When you add keys, you get a new JWKSet object
<?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.
$newJwkset = $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.
$newJwkset = $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);