Skip to content

Latest commit

 

History

History
242 lines (173 loc) · 6.38 KB

README.md

File metadata and controls

242 lines (173 loc) · 6.38 KB

Encryption

license build Coverage Status

This library supports both asymmetric (using key pairs) and symmetric (single key) encryption. There is also a Hybrid encryption which uses both asymmetric and symmetric. Both encrypted data and signatures are returned as a Base64 encoded string.

Asymmetric Encryption

Generating Keys

To generate a key pair

use Encryption\KeyPair;
$keyPair = KeyPair::generate();

$publicKey = $keyPair->publicKey(); // this is used to encrypt data
$privateKey = $keyPair->privateKey(); // this is to decrypt data
$string = $keyPair->toString(); // combines both key into a single string

Generate accepts the following options:

  • size: default:4096 the size of the key
  • passphrase: a password to encrypt the key with

Working with Private Keys

To create a PrivateKey object using a private key string, pass this to the constructor

use Encryption\PrivateKey;
$privateKey = new PrivateKey($string);
$privateKey = new PrivateKey($string, ['passphrase' => 'secret']));

To create a PrivateKey object by loading from a file

use Encryption\PrivateKey;
$privateKey = PrivateKey::load($path);
$privateKey = PrivateKey::load($path, ['passphrase' => 'secret']);

Things you can do with the PrivateKey object

$encrypted = $privateKey->encrypt($data);
$decrypted = $privateKey->decrypt($encrypted); // decrypts data encrypted by public key
$signature = $privateKey->sign($data);
$publicKey = $privateKey->extractPublicKey();
$bits = $privateKey->bits(); // 4096
echo $privateKey->toString();

You can also generate a private key using the static method generate, this will return a new PrivateKey object.

$privateKey = PrivateKey::generate();

Working with Public Keys

To create a PublicKey object using a public key string, pass this to the constructor

use Encryption\PublicKey;
$publicKey = new PublicKey($string);

To create a PublicKey object by loading from a file

use Encryption\PublicKey;
$publicKey = PublicKey::load($path);

Things you can do with the PublicKey object

$encrypted = $publicKey->encrypt($data);
$decrypted = $publicKey->decrypt($encrypted); // decrypts data encrypted by private key
$signature = $publicKey->verify($data, $signature);
$fingerprint = $publicKey->fingerprint(); // D52A E482 CBE7 BB75 0148 3851 93A3 910A 0719 994D
$bits = $publicKey->bits(); // 4096
echo $publicKey->toString();

Keychain

You can also manage keys with Keychain

$keychain = new Keychain(__DIR__ . '/keys');

Creating keys and adding to the Key Chain

To create a private and public key pair and add this to the Keychain, you can pass an email address, username, UUID or any other unique id.

$keychain->create('jon@example.com');

You can also set an expiry date for the key

$keychain->create('jon@example.com',[
    'expires' => '+ 1 year'
]);

Adding

When you add a private key, the public key will be extracted and added to the same document.

To add a private or public key from a string.

$keychain->add('user@example.com',(string) $privateKey);

Importing

When you add a private key, the public key will be extracted and added to the same document.

To import an existing public key or private/public key pair

$keychain->import('user-1979', __DIR__ .'/privateKey');

You can also set an expiry date for the key

$keychain->import('user-1979', __DIR__ .'/publicKey',[
    'expires' => '+ 1 year'
]);

Get

To get a key and data

$key = $keychain->get('jon@example.com');
/*
DocumentStore\Document Object
(
    [id] => 784e148db03ac07ff34ae57c29b01549
    [name] => user@example.com
    [privateKey] => -----BEGIN PRIVATE KEY-----
MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEA0BaIweRiLW1Uunxw
NrPr9GaNWtnr+FbzsY8DNf894yI4n6q47s7yTPCFmHuIDzKaYx0xdS3L2XcY3HYg
ctPUNQIDAQABAkAMQ/fFrgeXc+VVpLYck1hqLI1SeJvvJHjy02I2EZh9RdDcBKi9
+MOuP+TzkVL0w1QAFgB8nPGblPjUB6FMhkwVAiEA9VmWwKxlTevev7XcOUYSOabv
qHeqab6aY8H1+o9+e3MCIQDZHuDTTizUW4frKhvtKiBkwAV4YdErVM9LNFC+TFTX
twIhAL8o/FJGf+/EVRtdoKZnOA//Rz8lbXtSbIxJNVPxtYSNAiBhI5CA2WPzKnRY
AUH3TLarfMG1x0W29j28Ls7FJQ98ZwIgH5Esr246hK1bSGO4R2Z6yFCcBfo1Sgib
bjupP+8HbUs=
-----END PRIVATE KEY-----
    [publicKey] => -----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANAWiMHkYi1tVLp8cDaz6/RmjVrZ6/hW
87GPAzX/PeMiOJ+quO7O8kzwhZh7iA8ymmMdMXUty9l3GNx2IHLT1DUCAwEAAQ==
-----END PUBLIC KEY-----

    [fingerprint] => E010 6888 BE78 1571 D35A D3CC 22C7 62D3 6025 E288
    [expires] => 2050-01-01 12:00:00
    [type] => key-pair
    [comment] => foo
    [created] => 2020-11-20 17:07:41
)
*/

Delete

To delete a key and data

$keychain->delete('jon@example.com');

List

To get a list of keys

$keychain->list();

Symmetric Encryption

First you will need to generate a key that is 256 bit/32 bytes

$crypto = new SymmetricEncryption();
$key = $crypto->generateKey(); // 3LSpUJL4s0HNLun4T1KcheGjrVtCjaQ7

To encrypt a string

$crypto = new SymmetricEncryption();
$encrypted = $crypto->encrypt($text, $key);

To decrypt a string

$crypto = new SymmetricEncryption();
$decrypted = $crypto->decrypt($text, $key);

Hybrid Encryption

This can only decrypt data encrypted with the Hybrid Encryption class

Hybrid encryption uses both asymmetric and symmetric encryption. With hybrid encryption there is no limit on message size.

$publicKey = PublicKey::load($pathToPublicKey);
$privateKey = PrivateKey::load($pathToPrivateKey);

$crypto = new HybridEncryption();

$encrypted = $crypto->encrypt($data, $publicKey);
echo $crypto->decrypt($encrypted, $privateKey);

By default encrypted/signed data is wrapped in a ENCRYPTED DATA or SIGNATURE boundary, however this can be disabled when encrypting or signing data. For example

-----BEGIN ENCRYPTED DATA-----
eGrjYfLFQI/gVWfpZeEA05q7Swb9gaKRalZnBZ788mGXiOhj1+f+a2RLJxDu24FE1HnFd70YcPAAdWme1Lu0yQ==
-----END ENCRYPTED DATA-----

Decryption and signature verification will remove boundaries automatically if they are found present in the data.