Cryptography

Table of Contents

  1. Introduction
  2. Hashing
    1. bcrypt
  3. Encryption
    1. Encryption Keys
    2. Encrypting Data
    3. Decrypting Data

Introduction

Keeping user data secure is of the utmost importance. Unfortunately, PHP's built-in cryptographic support is somewhat fragmented and not easy to use. Lucky for you, Opulence has a Cryptography library to simplify all this.

Hashing

Hashers take input and perform a one-way mapping to a hashed value. It is impossible to decrypt a hashed value because of the way this mapping is generated. This hashes suitable for storing sensitive data, like user passwords.

bcrypt

bcrypt is a popular password hashing function. It accepts a "cost" parameter, which adjusts the CPU cost to hash a password. This slows down attacks against compromised data. Increasing the cost parameter by one causes the hashing to take twice as long, which future-proofs it as CPUs get faster. Let's take a look at how to use it:

use Opulence\Cryptography\Hashing\BcryptHasher;

$bcryptHasher = new BcryptHasher();

// Let's create a hash with a pepper of "bar"
// $hash is automatically salted and suitable for database storage
$hashedValue = $bcryptHasher->hash('foo', ['cost' => 10], 'bar');

To verify that an unhashed value hashes to a particular value, use verify():

$unhashedValue = 'foo';
echo $bcryptHasher->verify($hashedValue, $unhashedValue, 'bar'); // 1

Encryption

Sometimes, your application needs to encrypt data, send it to another component, and then decrypt it. This is different from hashing in that encrypted values can be decrypted. To make this process as secure and simple as possible, Opulence has an easy-to-use wrapper around OpenSSL in its Encrypter class:

use Opulence\Cryptography\Encryption\Ciphers;
use Opulence\Cryptography\Encryption\Encrypter;
use Opulence\Cryptography\Encryption\EncryptionException;
use Opulence\Cryptography\Encryption\Keys\Password;

$encrypter = new Encrypter(new Password('mySecretApplicationPassword'));

You can change the underlying OpenSSL cipher by passing it in via the second parameter:

$encrypter = new Encrypter(new Password('mySecretApplicationPassword'), Ciphers::AES_128_CBC);

Note: The default cipher is AES-256-CTR. It is strongly recommended you use an AES CTR or CBC cipher such as AES-256-CTR or AES-256-CBC.

Encryption Keys

Encrypter takes in a secret. This secret can either be:

Opulence uses a key derivation function (PBKDF2 by default) to turn your key or password into cryptographically-strong encryption and authentication keys.

Note: The encryption key is used to encrypt/decrypt data. The authentication key is used to create and verify the HMAC contained in the encrypted value.

To use a cryptographic key in your encrypter, simply pass in a Key object:

use Opulence\Cryptography\Encryption\Keys\Key;

$encrypter = new Encrypter(new Key(random_bytes(32)));

Encrypting Data

try {
    $encryptedData = $encrypter->encrypt('foobar');
} catch (EncryptionException $ex) {
    // Handle the exception
}

If there was any issue encrypting the data, an Opulence\Cryptography\Encryption\EncryptionException will be thrown.

Decrypting Data

try {
    $encryptedData = $encrypter->encrypt('foobar');
    $decryptedData = $encrypter->decrypt($encryptedData);
} catch (EncryptionException $ex) {
    // Handle the exception
}

// Verify the decrypted data matches our original value
echo $decryptedData === 'foobar'; // 1

If there was any issue decrypting the data, an Opulence\Cryptography\Encryption\EncryptionException will be thrown.