Skip to main content

Passwordless Cryptography Library

Sponsor Build Status Opensource ByJG GitHub source GitHub license GitHub release

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:

  1. The library uses an 8-byte scrolling window to extract random portions from the key seed entries
  2. A 4-byte header encodes the key seed entry indices and extraction offsets
  3. The encrypted data includes this header (embedded in the payload)
  4. 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:

  1. The 4-byte header is extracted from the encrypted payload
  2. Using the same key seed and the header, the exact key and IV are reconstructed using the same offsets
  3. 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

Installation

composer require "byjg/crypto"

Running the tests

./vendor/bin/phpunit

Dependencies


Open source ByJG