Installation
composer require spomky-labs/aes-key-wrap
First Use Case: Wrapping a Key
use SpomkyLabs\KeyWrap\KeyWrap;
$keyWrap = new KeyWrap('my-secret-key-32bytes'); // Must be 32 bytes for AES-256
$wrappedKey = $keyWrap->wrap('key-to-wrap-32bytes'); // Input must also be 32 bytes
First Use Case: Unwrapping a Key
$unwrappedKey = $keyWrap->unwrap($wrappedKey);
Where to Look First
Key Rotation
$masterKey = 'new-master-key-32bytes';
$keyWrap = new KeyWrap($masterKey);
$wrappedOldKey = $keyWrap->wrap($oldMasterKey);
Secure Storage
.env):$wrappedKey = base64_encode($keyWrap->wrap($sensitiveKey));
config(['services.api.key' => $wrappedKey]);
$keyWrap->unwrap(base64_decode(config('services.api.key')));
Integration with Laravel
$this->app->singleton(KeyWrap::class, function ($app) {
return new KeyWrap(config('services.master_key'));
});
$wrapped = $this->app->make(KeyWrap::class)->wrap(config('app.encryption_key'));
config(['app.encryption_key_wrapped' => $wrapped]);
Batch Operations
$keys = ['key1', 'key2', 'key3'];
$wrappedKeys = array_map([$keyWrap, 'wrap'], $keys);
wrapped_key_v1, wrapped_key_v2).defuse/php-encryption for asymmetric key exchange:
$publicKey = ...;
$sharedSecret = openssl_encrypt($masterKey, 'AES-256-CBC', $publicKey, ...);
$keyWrap = new KeyWrap($sharedSecret);
Key Length Requirements
InvalidArgumentException otherwise.if (strlen($key) !== 32) {
throw new \InvalidArgumentException('Key must be 32 bytes.');
}
RFC Compliance
$keyWrap = new KeyWrap($masterKey, KeyWrap::RFC5649);
Base64 Handling
$wrapped = base64_encode($keyWrap->wrap($key)); // Store
$keyWrap->unwrap(base64_decode($wrapped)); // Retrieve
Thread Safety
Invalid Output? Verify:
Performance Wrapping/unwrapping is O(1) but I/O (e.g., DB reads) may bottleneck. Cache wrapped keys if reused frequently.
Custom Key Derivation
Pre-process keys with hash_hmac or sodium_crypto_kdf before wrapping:
$derivedKey = hash_hmac('sha256', $key, $salt, true);
$keyWrap->wrap($derivedKey);
Logging
Wrap unwrap() in a try-catch to log failed decryption attempts (potential brute-force):
try {
$keyWrap->unwrap($wrappedKey);
} catch (\Exception $e) {
\Log::warning("Failed to unwrap key: {$e->getMessage()}");
}
Testing
Use the library’s test suite as a reference for edge cases (e.g., empty keys, non-ASCII data). Mock KeyWrap in unit tests:
$mockWrap = $this->createMock(KeyWrap::class);
$mockWrap->method('unwrap')->willReturn('unwrapped-key');
How can I help you explore Laravel packages today?