In addition to its core functionality, Halite offers some useful APIs for solving common problems.
Cookie- Authenticated encryption for your HTTPS cookiesFile- Cryptography library for working with filesPassword- Secure password storage and password verification API
Unlike the core Halite APIs, the Cookie class is not static. You must create an
instance of Cookie and work with it.
$enc_key = \ParagonIE\Halite\KeyFactory::loadEncryptionKey('/path/to/key');
$cookie = new \ParagonIE\Halite\Cookie($enc_key);From then on, all you need to do is use the fetch() and store() APIs.
Storing data in an encrypted cookie:
$cookie->store(
'auth',
['s' => $selector, 'v' => $verifier],
time() + 2592000
);Fetching data from an encrypted cookie:
$token = $cookie->fetch('auth');
var_dump($token); // array(2) ...Halite's File class provides streaming file cryptography features, such as
authenticated encryption and digital signatures. File allows developers to
perform secure cryptographic operations on large files with a low memory
footprint.
The File API looks like this:
File::checksum(file,AuthenticationKey?,bool?):stringFile::encrypt(file,file,EncryptionKey)File::decrypt(file,file,EncryptionKey)File::seal(file,file,EncryptionPublicKey)File::unseal(file,file,EncryptionSecretKey)File::sign(file,EncryptionSecretKey):stringFile::verify(file,EncryptionPublicKey):bool
The file type indicates that the argument can be either a string containing
the file's path, or a resource (open file handle).
Each of these features is designed to work in a streaming fashion.
Basic usage:
$checksum = \ParagonIE\Halite\File::checksum('/source/file/path');If for some reason you desire to use a keyed hash rather than just a plain one,
you can pass an AuthenticationKey to
an optional second parameter, or null.
$keyed = \ParagonIE\Halite\File::checksum('/source/file/path', $auth_key);Finally, you can pass true as the optional third argument if you would like a
raw binary string rather than a hexadecimal string.
$keyed_checksum = \ParagonIE\Halite\File::checksum('/source/file/path', null, true);If you need to encrypt a file larger than the amount of memory available to PHP,
you'll run into problems with just the basic \ParagonIE\Halite\Symmetric\Crypto
API. To work around these limitations, use File::encrypt() instead.
For example:
\ParagonIE\Halite\File::encrypt(
$inputFilename,
$outputFilename,
$enc_key
);This will encrypt the contents of the file located at $inputFilename and write
its contents to $outputFilename.
Decryption is straightforward as well:
\ParagonIE\Halite\File::decrypt(
$inputFilename,
$outputFilename,
$enc_key
);This feature encrypts files with a public key so that they can be decrypted offline with a secret key.
$seal_keypair = \ParagonIE\Halite\KeyFactory::generateEncryptionKeyPair();
$seal_secret = $seal_keypair->getSecretKey();
$seal_public = $seal_keypair->getPublicKey();Sealing the contents of a file using Halite:
\ParagonIE\Halite\File::seal(
$inputFilename,
$outputFilename,
$seal_public
);Opening the contents of a sealed file using Halite:
\ParagonIE\Halite\File::unseal(
$inputFilename,
$outputFilename,
$seal_secret
);First, you need a key pair.
$sign_keypair = \ParagonIE\Halite\KeyFactory::generateSignatureKeyPair();
$sign_secret = $sign_keypair->getSecretKey();
$sign_public = $sign_keypair->getPublicKey();Signing the contents of a file using your secret key:
$signature = \ParagonIE\Halite\File::sign(
$inputFilename,
$sign_secret
);Verifying the contents of a file using a known public key:
$valid = \ParagonIE\Halite\File::verify(
$inputFilename,
$sign_public,
$signature
);Like checksumFile(), you can pass an optional true to get a raw binary
signature instead of a hexadecimal-encoded string.
This feature serves a very narrow use case: You have the webserver and database on separate hardware, and would like to prevent a database compromise from leaking the actual password hashes.
If your webserver and database server are the same machine, there is no advantage to using this feature over libsodium's Argon2 implementation.
Hashing then Encrypting a password:
$stored_hash = \ParagonIE\Halite\Password::hash(
$plaintext_password, // HiddenString
$encryption_key // \ParagonIE\Halite\Symmetric\EncryptionKey
);Validating a password:
try {
if (\ParagonIE\Halite\Password::verify(
$plaintext_password, // HidddenString
$stored_hash, // string
$encryption_key // \ParagonIE\Halite\Symmetric\EncryptionKey
)) {
// Password matches
}
} catch (\ParagonIE\Halite\Alerts\InvalidMessage $ex) {
// Handle an invalid message here. This usually means tampered ciphertext.
}