# Key (JWK)

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.

{% hint style="warning" %}
Please note a JWK object is an immutable object. If you change a value using a setter, it will return a new object.
{% endhint %}

```php
<?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);
```

## Generate A New Key

This framework is able to create private and public keys on the fly using the `JWKFactory`. 4 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

{% hint style="info" %}
The `none` algorithm needs a key of type `none`. This is a specific key type that must only be used with this algorithm.
{% endhint %}

### Octet String

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
<?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
<?php

use Jose\Component\KeyManagement\JWKFactory;

$jwk = JWKFactory::createFromSecret(
    'My Secret Key',       // The shared secret
    [                      // Optional additional members
        'alg' => 'HS256',
        'use' => 'sig'
    ]
);
```

### RSA Key Pair

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
<?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
    ]);
```

### Elliptic Curve Key Pair

The following example will show you how to create a `EC` key.

```php
<?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)

#### Octet Key Pair

The following example will show you how to create a `OKP` key.

```php
<?php

use Jose\Component\KeyManagement\JWKFactory;

$key = JWKFactory::createOKPKey('X25519');
```

The supported curves are:

* `Ed25519` for signature/verification only
* `X25519` for encryption/decryption only

### None Key

The `none` key type is a special type used only for the `none` algorithm.

```php
<?php

use Jose\Component\KeyManagement\JWKFactory;

$key = JWKFactory::createNoneKey();
```

## Create Key From External Sources

### From Values

In case you already have key values, you can create a key by passing those values as an argument:

```php
<?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',
]);
```

### From A Key File

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
<?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
    ]
);
```

### From A PKCS#12 Certificate

You can convert a PKCS#12 Certificate into a JWK. Encrypted certificates are also supported.

```php
<?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
    ]
);
```

### From A X.509 Certificate

You can convert a X.509 Certificate into a JWK.

```php
<?php

use Jose\Component\KeyManagement\JWKFactory;

$key = JWKFactory::createFromCertificateFile(
    '/path/to/my/key/file.crt', // The filename
    [
        'use' => 'sig',         // Additional parameters
    ]
);
```

{% hint style="info" %}
Please note that X.509 certificates only contains public keys.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://web-token.spomky-labs.com/v4.0/the-components/key-jwk-and-key-set-jwkset/key-management.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
