Passwordless Cryptography Library
A cryptography library for symmetric encryption with an innovative keyless exchange mechanism.
How it works
The algorithm is well-known, but the major problem is HOW to store and exchange symmetric keys securely. This library solves this with an innovative "keyless" exchange mechanism:
Key Seed Instead of Keys
Instead of storing or transmitting actual encryption keys, this library uses a key seed - a list of 2-255 entries of 32 bytes each (the default is 32 entries). Both the sender and receiver must have the same key seed.
Dynamic Key Generation with Scrolling Window
For each encryption operation:
- The library uses an 8-byte scrolling window to extract random portions from the key seed entries
- A 4-byte header encodes the key seed entry indices and extraction offsets
- The encrypted data includes this header (embedded in the payload)
- The actual key and IV are never stored or transmitted
The scrolling window can extract 8 bytes from any position (0-24) within each 32-byte key seed entry, providing 25 possible positions per entry, resulting in millions of possible key/IV combinations.
Keyless Decryption
When decrypting:
- The 4-byte header is extracted from the encrypted payload
- Using the same key seed and the header, the exact key and IV are reconstructed using the same offsets
- The data is decrypted and authenticated
This means you can securely exchange encrypted data without ever transmitting the actual encryption keys - only a 4-byte header that's meaningless without the key seed!
Usage
<?php
$keySet = new \ByJG\Crypto\KeySet(
[
// 2-255 entries of 32 bytes each
]
);
$object = new \ByJG\Crypto\OpenSSLCrypto(
$algorithm,
$keySet
);
$text = 'My text needs to be cryptographed';
$encrypted = $object->encrypt($text);
echo $object->decrypt($encrypted);
- The algorithm needs to be one of the algorithms returned by
openssl_get_cipher_methods(). - The second parameter is the key seed. It is a list of 2-255 entries of 32 bytes each. You can generate it using the command
\ByJG\Crypto\KeySet::generateKeySet()
Example
Below a full example:
<?php
require "vendor/autoload.php";
$keySet = new \ByJG\Crypto\KeySet(
[
'14dca647bcc087f67b1528cea11094838f5bd2276a08dcabc491c1823afc51dd',
'9cc0fd22a3dc2fb3d444e0721e5d02f5c39f9d6b7c41c010a28e06e861f54c8b',
'e7b965f8b401c06d5180f50f49eb9797ad24fef62b20bcde03456d4ea4006e83',
'd06b7ff23bd76b19bc1283f28a00bb91cccdf6bd163354f099710898e31ac487',
'b4bed7d50032556780b303f8cfea612b637ab8935443af4219dd9eb06d4d7b01',
'0b2f4cb0107ab6946938f2c836cdca74f7e2b1c7482dd2942720ccc755b20097',
'dcd24b8aa48d2bcd2d0b19764088e7d4343cfee6a15c9f805b58e45b6224c2f5',
'628b889c7471e149724973ee96a1c5728c61f11c45e3ae6314a321c7b3488bde',
'4e10b6af85f83951f23514d3c9d1248d1a1777ff114a6768ae116c2a72bc4bc3',
'da13fce62e22f5919efe8f0cb498f067797e5fc68a94c45c9ae9d1717f82555d',
'5bd0600dbca418c8166ffc0617e24f472f147424c58dfd4859cde2cd6a98dee7',
'533c32c8e010920471e2462ba88f9c63278f9cdd7f12adde4a6e15595a56783d',
'13beb307499b0d911c6ea4c12b9e1131c51693b8918ac5a76c09e86477b28b5a',
'e966e4d659c99a58da41c305de0e479b4885f83ddb30476955ad28fd9b9e2d7a',
'b7a6b7535547dd27963e2bb34630edcf81364ae998fdd68356772b300b65dbbc',
'f00a1fd6ac5e8bb774c66ef908052f95c9d654df117958fc13a1b5056ddb331b',
'297e13efdd279687af8c70158b446a4724c4a17989eb0fc93ee87606e958fc9c',
'27a7e110e61076e4901822c940c294f29abbc659370480cd234473c0c90e10ef',
'd28e4c29007269902711ae177e4c882a4893f1fa47a987872879b0a785cf8c20',
'f3be6dc7b34df6aafdc3bd5705fd37d73291ac5a15fe7fd4d39497b43e87dd28',
'8782a68a904d269ae01bb1705dd1b59047749dd07b5b486e5b79b04660054c1e',
'21c05ba1cf9028f35ab3fd02e46dab733f8957e6b003e5ba8ea9917fa1ad2809',
'722a9fe048b6aef9407c5ef7cb76896422ef0add38e5db4afd649a7c7ea1f905',
'6b233fb3e56e55236ab6c862cb982c4df5dde4ca44361b02cd5915160966d3c5',
'bd6802bc1252316c44e277bbdfdac8712223a445899d77f9d996286f2c499668',
'e58088cdef444792501a21813ff520c3fd05cf249b958e0b92fd50142eff74d5',
'9ca20ff424531314ccfd0e067ced0fbc078df65c77d9c5d30470058e6e2fc83c',
'd50f461eab2cb5855d44bb753710193970c646b6017ce2522081d337188ee28d',
'9473c14be30ae90db3d16014a538ce6b19d2477bbf1294793540c19559ed1363',
'20ad5fed300d150305ad48eb1f9b72cc5d24645d3e736ad5c66e6aeee6dcea88',
'522b058ea3c9cb29c010c431b30e6b6449994e03dc6434965c941e8c465881eb',
'dec0adad3df3e8c9f5eb135902970c59cd75fc7c1b52ba41ce8ec5b1351e74dc',
];
);
$object = new \ByJG\Crypto\OpenSSLCrypto(
'aes-256-cbc',
$keySet
);
$enc = $object->encrypt('My secret text needs to be encrypted');
echo $object->decrypt($enc) . "\n";
Important
- Do not share the key seed.
- You'll only be able to decrypt the text if you have the same key seed used to encrypt it.
Additional Documentation
- Advanced uses of KeySet class
- Interoperability with JavaScript
- Keyless Exchange - How it works in detail
Installation
composer require "byjg/crypto"
Running the tests
./vendor/bin/phpunit