oire/colloportus

This package is abandoned and no longer maintained. The author suggests using the oire/iridium package instead.

Password hashing and encryption library.

v2.2 2021-01-23 10:47 UTC

This package is not auto-updated.

Last update: 2021-03-07 23:27:04 UTC


README

Note! This library is not maintained anymore.

Please use Iridium security library instead.

Latest Version on Packagist MIT License

Welcome to Colloportus, a password hashing and data encryption library!
This library can be used for hashing passwords, as well as for encrypting data that needs to be decrypted afterwards. It wraps Bcrypt-SHA384 in Authenticated Encryption. A simplified fork of Password Lock by Paragon Initiative Enterprises.
Integrates parts of Defuse PHP Encryption for authenticated symmetric-key encryption.
Depends on Oirë Base64 for encoding binary data to a storable format.

About the Name

Colloportus is a magical spell in the well-known Harry Potter series. It locks doors in a very hard-to-open way, and such a door is completely impossible to open for muggles, i.e., non-wizarding people. I decided to use this as a name for my simplified fork of PasswordLock.
The method names are also simplified: lock, check and flip instead of HashAndEncrypt, DecryptAndVerify and RotateKey.

Requirements

Requires PHP 7.3 or later with mbString and openSSL enabled.

Installation

Install via Composer:

composer require oire/colloportus

Running Tests

Run ./vendor/bin/phpunit in the projects directory.

Compatibility with Earlier Versions of PHP

If you want a version compatible with PHP 7.1.2, please install version 1 instead:

composer require "oire/colloportus ^1"

Usage Examples

Hash and Encrypt a Password

use Oire\Colloportus\Colloportus;
use Oire\Colloportus\Exception\ColloportusException;

// Actually you need to create a key beforehand and save it somewhere, for example, in a .env file
$key = Colloportus::createKey();

if (!empty($_POST['password'])) {
    try {
        $storeMe = Colloportus::lock($_POST['password'], $key);
    } catch (ColloportusException $e) {
        // Handle errors
    }
}

Decrypt and Verify a Password

if (!empty($_POST['password'])) {
    try {
        $verified = Colloportus::check($_POST['password'], $storeMe, $key);
    } catch (ColloportusException $e) {
        // Handle errors
    }

    if ($verified) {
        // Success!
	}
}

Encrypt Some Data that Need to Be Decrypted Afterwards

Note! Do not use this for passwords, they must not be back-decryptable. If you want to store a password, you must hash it (see above).

$data = 'Mischief managed!';
$encrypted = Colloportus::encrypt($data, $key);
$decrypted = Colloportus::decrypt($encrypted, $key);
var_export($decrypted === $data);
// => true

Re-encrypt Data with a Different Encryption Key

$newKey = Colloportus::createKey();

try {
    $newHash = Colloportus::flip($storeMe, $key, $newKey);
} catch (ColloportusException $e) {
    // Handle errors
}

On Error Handling

Colloportus has various exceptions that are thrown when something fails:

  • A generic ColloportusException which is always safe to catch. All other exceptions inherit from it;
  • EncryptionException is thrown whenever data encryption fails;
  • DecryptionException is thrown whenever data decryption fails;
  • PasswordException is thrown whenever a password-related call fails;
  • KeyException is thrown when any key-related call fails.

Methods

All Colloportus methods are public and static, so no class instance is required. The methods are documented in the code comments, but their description is given below for rerefence.
We recommend to wrap every call in try...catch since Colloportus throws ColloportusException in case of errors.

  • public static function createKey(): string — Creates a random encryption key. Returns a storable, human-readable random key.
  • public static function encrypt(string $plainText, string $key): string — Encrypts given string data with a given key. Returns the encrypted data.
  • public static function decrypt(string $cipherText, string $key): string — Decrypts given cipher text with a given key. Returns the decrypted plain text.
  • public static function lock(string $password, string $key): string — Locks given password with a given key. Returns a storable result.
  • public static function check(string $password, string $cipherText, string $key): bool — Verifies the given password against a given cipher text. Returns true on success or false on failure.
  • public static function flip(string $cipherText, string $oldKey, string $newKey): string — Allows to re-encrypt any encrypted data with a different key (for example, if the old key is compromised and the hashes are not). Returns the data encrypted with the new key.
  • public static function keyIsValid(string $key): bool — Checks if a given key is valid. As the keys are random, basically checks only the length of the key and whether it can be decoded from Oirë implementation of Base64. Returns true if the key is valid, false otherwise.

Differences between Password Lock and Colloportus

  • All methods needed for encryption/decryption are provided along with the hashing/verifying methods.
  • Back-porting to older PHP versions is removed, hence PHP 7.1.2 is required (the hash_hkdf() method was added in this particular version).
  • Custom string processing implementations are removed, mbstring is required.
  • Version header check is removed.
  • encrypt() and, subsequently, Lock() returns URL/filename-safe Base64 data instead of hexits.
  • All sha256 instances are changed to sha384.
  • Code style changed to match Oirë standards.

Contributing

All contributions are welcome. Please fork, make a feature branch, hack on the code, run tests, push your branch and send a pull-request.

License

Copyright © 2017-2021, Andre Polykanine also known as Menelion Elensúlë, The Magical Kingdom of Oirë.
This software is licensed under an MIT license.