Installation:
composer require web-token/jwt-encryption
Ensure you also install the main JWT framework for full functionality:
composer require web-token/jwt-framework
First Use Case: Encrypt a JWT payload using a shared secret or public/private key pair:
use WebToken\JWT\Encryption\Encryption;
use WebToken\JWT\Encryption\Key;
// Shared secret (symmetric)
$secret = 'your-256-bit-secret';
$key = new Key($secret, Key::ENCRYPTION_ALGORITHM_A256KW);
$encryption = new Encryption($key);
// Encrypt a JWT payload
$encrypted = $encryption->encrypt('{"user_id":123,"role":"admin"}');
Where to Look First:
src/Encryption.php for core logic.src/Key.php for key management.Symmetric Encryption (Shared Secret):
$key = new Key('shared-secret', Key::ENCRYPTION_ALGORITHM_A256KW);
$encryption = new Encryption($key);
// Encrypt
$encrypted = $encryption->encrypt(json_encode(['data' => 'sensitive']));
// Decrypt
$decrypted = $encryption->decrypt($encrypted);
Asymmetric Encryption (RSA/OAEP):
$privateKey = file_get_contents('private.pem');
$publicKey = file_get_contents('public.pem');
$privateKeyObj = new Key($privateKey, Key::ENCRYPTION_ALGORITHM_RSA_OAEP);
$publicKeyObj = new Key($publicKey, Key::ENCRYPTION_ALGORITHM_RSA_OAEP);
$encryption = new Encryption($publicKeyObj); // Encrypt with public key
$encrypted = $encryption->encrypt('{"data":"sensitive"}');
$decryption = new Encryption($privateKeyObj); // Decrypt with private key
$decrypted = $decryption->decrypt($encrypted);
Integration with Laravel:
.env (e.g., JWT_SECRET=your-secret).Encryption class:
$this->app->singleton('jwt.encryption', function ($app) {
$secret = config('jwt.secret');
$key = new Key($secret, Key::ENCRYPTION_ALGORITHM_A256KW);
return new Encryption($key);
});
public function encryptData(Request $request, Encryption $encryption) {
$encrypted = $encryption->encrypt($request->input('data'));
return response()->json(['encrypted' => $encrypted]);
}
JWT-Specific Usage:
Combine with web-token/jwt-framework for encrypted JWTs:
use WebToken\JWT\Builder;
use WebToken\JWT\Signature\Hmac\Sha256;
$builder = new Builder();
$builder->withPayload(['user_id' => 123]);
$builder->withEncryption($encryption); // Inject Encryption instance
$jwt = $builder->getToken($secret, 'HS256');
Key Management:
Key::ENCRYPTION_ALGORITHM_*) matches the key type (e.g., A256KW for AES, RSA_OAEP for RSA).
// ❌ Wrong: Using RSA key with AES algorithm
$key = new Key($rsaPrivateKey, Key::ENCRYPTION_ALGORITHM_A256KW);
Key Size Requirements:
A256KW. Shorter keys will throw exceptions.RSA_OAEP.Base64 Encoding:
$key = base64_decode('your-base64-key');
$keyObj = new Key($key, Key::ENCRYPTION_ALGORITHM_A256KW);
Thread Safety:
Encryption class is not thread-safe. Avoid sharing instances across concurrent requests (e.g., in Laravel, bind it as a singleton only if keys are immutable).Error Handling:
WebToken\JWT\Exception\InvalidTokenException. Catch and handle gracefully:
try {
$decrypted = $encryption->decrypt($encryptedData);
} catch (InvalidTokenException $e) {
Log::error('Decryption failed: ' . $e->getMessage());
abort(403, 'Invalid token');
}
Verify Key Format:
$key = 'your-secret';
if (strlen($key) !== 32) {
throw new \RuntimeException('AES key must be 32 bytes (256 bits)');
}
Check Algorithm Support:
openssl_encrypt for AES, openssl_private_decrypt for RSA). Test with:
php -m | grep openssl
Logging Encrypted Data:
Log::debug('Encrypted data hash:', hash('sha256', $encryptedData));
Custom Key Storage:
Key to support custom key sources (e.g., AWS KMS, HashiCorp Vault):
class CustomKey extends Key {
public function __construct(string $keyId, string $algorithm) {
$key = $this->fetchFromVault($keyId); // Custom logic
parent::__construct($key, $algorithm);
}
}
Hybrid Encryption:
web-token/jwt-framework to encrypt JWT claims:
$builder = new Builder();
$builder->withPayload(['data' => $encryption->encrypt('sensitive')]);
Performance Optimization:
Encryption instances (they are stateless) but avoid recreating keys unnecessarily:
// Good: Reuse key and encryption instance
$key = new Key($secret, Key::ENCRYPTION_ALGORITHM_A256KW);
$encryption = new Encryption($key);
// Encrypt/decrypt multiple times...
Testing:
Encryption class in unit tests to avoid key leakage:
$mockEncryption = $this->createMock(Encryption::class);
$mockEncryption->method('encrypt')->willReturn('mocked-encrypted-data');
$mockEncryption->method('decrypt')->willReturn('mocked-decrypted-data');
How can I help you explore Laravel packages today?