CryptoMañana Documentation

The Object-Oriented PHP Cryptography Framework

Hash Function

    The definition of a hash function is any function that can be used to map data of arbitrary size to fixed-size values. The output values returned by this type of function are called hash values, hash codes, digests or simply hashes. In addition, a cryptographic hash function is an algorithm that takes an arbitrary amount of data, for example user credentials, and produces a fixed-size output of one-wway enciphered text called a hash value. That encrypted text can then be stored instead of the password itself and be used to verify the user. This output digest acts as a secure checksum of the input data or file and can be used to verify the integrity of the data, authenticate the ownership or verify the source of the file. Cryptographic hash functions can have a lot of different parameters, depending on their type. They are frequently used with a cryptographic salt that is made up of pseudo-random bits that are added in some way to the input, to increase the resistance of the function against various attacks to compromise the used digestion algorithm. The use cases of this type of cryptographic calculation are tremendous, the input digestion algorithms are mostly used for:

    The CryptoMañana (CryptoManana) cryptography framework provides object-oriented components for each of the above use cases and has a huge set of available realizations.

Basic Methods

    The provided software components for hashing in the cryptography model always include:

hashData() // hash a string of binary data
setSalt() // set the salting string
getSalt() // get the current salting string
setSaltingMode() // set a salting operation mode
getSaltingMode() // get the current salting operation mode
setDigestFormat() // set a output format for the digest string
getDigestFormat() // get the current output digest string presentation format

Note: The simplest way to generate a cryptographic configuration is via the framework, by using the TokenGenerator component (which will be examined in more detail in one of the next pages of this manual).

Input Salting Techniques

    As mentioned previously, the adding of a cryptographic salt string or a nonce to the input can increase the overall security of a hash function (if done correctly). This cryptography framework provides 9 salting techniques that can be easily configured. The specific techniques can be enabled via the setSaltingMode() setter method (the default setting is SALTING_MODE_APPEND) and the available mode constants per each object. The following options are available for each object:

Output Digestion Format

    The software framework supports a vast variety of well-known and frequently used data formats for the output digest value. Each hash function object provides 5 output formats that can be easily configured. The specific format can be enabled via the setDigestFormat() setter method (the default setting is DIGEST_OUTPUT_HEX_UPPER) and the available format setting constants per each object. The following options are available for each object:

Unkeyed Hash Functions

    The first supported type is the unkeyed hash function that has no parameters and is mostly used for data integrity checks. The supported algorithm/standard realizations at the \CryptoManana\Hashing namespace are:

    It is important to mention that the unkeyed hash components have 3 other methods available:

hashFile() // calculate a hash value for a file's content
hashObject() // calculate a hash value for an object's serialization state
repetitiveHashData() // do reparative hashing, like md5(md5('1234'))

    Here is a simple example for the usage of this type of hashing component:

use CryptoManana\Hashing\Sha1;
use \stdClass as stdClass;

$hasher = new Sha1();

$hasher->setSalt('SALT')
    ->setSaltingMode($hasher::SALTING_MODE_INFIX_INPUT) // or `Sha1::`
    ->setDigestFormat($hasher::DIGEST_OUTPUT_BASE_64_URL); // or `Sha1::`

// sha1('SALTdataTLAS')
echo 'Text Digest: ' . $hasher->hashData('data') . '<br>';

// sha1(sha1(sha1())))
echo '3x Digestion: ' . $hasher->repetitiveHashData('data', 3) . '<br>';

// has the content of this file
echo 'File Digest: ' . $hasher->hashFile(__FILE__) . '<br>';

// serialize and hash an empty object
echo 'Object Digest: ' . $hasher->hashObject(new stdClass()) . '<br>';

Keyed Hash Functions

    The second supported type is the keyed hash function that has an extra parameter for the calculation in the form of a key and is mostly used for data authentication checks or password storage purposes. The supported algorithm/standard realizations at the \CryptoManana\Hashing namespace are:

    It is important to mention that the keyed hash components have 6 other methods available:

hashFile() // calculate a hash value for a file's content
hashObject() // calculate a hash value for an object's serialization state
repetitiveHashData() // do reparative hashing, like md5(md5('1234'))
verifyHash() // time-safe verification of a digest against an input (@passwords)
setKey() // setter for the HMAC key
getKey() // getter for the HMAC key

    Here is a simple example for the usage of this type of hashing component:

use CryptoManana\Hashing\HmacSha1;
use \stdClass as stdClass;

$hasher = new HmacSha1();

$hasher->setKey('manana')
	->setSalt('4321')
	->setDigestFormat($hasher::DIGEST_OUTPUT_HEX_LOWER) // or `HmacSha1::`
	->setSaltingMode($hasher::SALTING_MODE_INFIX_SALT); // or `HmacSha1::`

$digest = $hasher->hashData('password');

echo $hasher->verifyHash('password', $digest) ?
    'The passwords match!' : 'The passwords are not the same!';
echo '<br>';

// hmacsha1('SALTdataTLAS')
echo 'Text Digest: ' . $hasher->hashData('data') . '<br>';

// hmacsha1(hmacsha1(hmacsha1())))
echo '3x Digestion: ' . $hasher->repetitiveHashData('data', 3) . '<br>';

// has the content of this file
echo 'File Digest: ' . $hasher->hashFile(__FILE__) . '<br>';

// serialize and hash an empty object
echo 'Object Digest: ' . $hasher->hashObject(new stdClass()) . '<br>';

$hasher->setKey('first key');
$digestOne = $hasher->hashData('data');

$hasher->setKey('second key');
$digestTwo = $hasher->hashData('data');

echo $digestOne === $digestTwo ?
    'The too digest are the same!' : 'The digests are different, CORRECT!';

Key Derivation Hash Functions

    The third supported type is the key derivation hash function that can have multiple extra parameters and is mostly used for the generation of huge sets of connected keys, data authentication checks or for secure dynamic configuration manipulations (“transforming before using”). The best feature for this type of hash function is that we can choose the output length of the digest based on the chosen algorithm. The supported algorithm/standard realizations at the \CryptoManana\Hashing namespace are:

    It is important to mention that the key derivation hash components have 7 other methods available:

repetitiveHashData() // do reparative hashing, like md5(md5('1234'))
setDerivationSalt() // set the internal derivation salt (for internal hashing)
getDerivationSalt() // get the current internal derivation salt
setContextualString() // set a key for the derivation (parallel execution)
getContextualString() // get the contextual string key
setOutputLength() // set a desired output length in bytes
getOutputLength() // get the currently set output length

    This type of component has 1 public constant available:

ALGORITHM_MAXIMUM_OUTPUT // The algorithm's maximum output in bytes

    Here is a simple example for the usage of this type of hashing component:

use CryptoManana\Hashing\HkdfSha1;

$hasher = new HkdfSha1();

$hasher->setDigestFormat($hasher::DIGEST_OUTPUT_RAW) // or `HkdfSha1::`
	->setSaltingMode($hasher::SALTING_MODE_APPEND) // or `HkdfSha1::`
	->setSalt('hit hard');

$hasher->setContextualString('crypto')
	->setDerivationSalt('manana')
	->setOutputLength(69);

$digestOne = $hasher->hashData('data');

$hasher->setContextualString('cryptomanana');
$digestTwo = $hasher->hashData('data');

echo $digestOne === $digestTwo ?
    'The too digest are the same!' : 'The digests are different, CORRECT!';
echo '<br>';

echo 'Text Digest: ' . $digestOne . '<br>';

$hasher->setContextualString('cryptomanana');
echo 'Text Digest (different context): ' . $digestTwo . '<br>';

// hkdfsha1(hkdfsha1(hkdfsha1()))
echo '3x Digestion: ' . $hasher->repetitiveHashData('data', 3) . '<br>';

Password Derivation Hash Functions

    The fourth supported type is the password-based derivation hash function that has multiple extra parameter for the calculation and is mostly used to protect passwords that need a hardware or parallel resistance defence. The used configurations with this type of function should aim a hashing time above 50 milliseconds for web based applications or up to 0.5 seconds for other purposes. It is important to say that the output digest here can be of different length, because some of the algorithms (like Argon2 or Bcrypt) can have a different salting string for each operation and also support a version of the algorithms used (inside the digest). The supported algorithm/standard realizations at the \CryptoManana\Hashing namespace are:

    It is important to mention that the Password-Based Key Derivation (version 2) components have 7 other methods available:

verifyHash() // time-safe verification of a digest against an input (@passwords)
setDerivationSalt() // set the internal derivation salt (for internal hashing)
getDerivationSalt() // get the current internal derivation salt
setOutputLength() // set a desired output length in bytes
getOutputLength() // get the currently set output length
setDerivationIterations() // set the internal iteration values
getDerivationIterations() // get the current iteration value

    This type of component has 1 public constant available:

ALGORITHM_MAXIMUM_OUTPUT // the algorithm's maximum output in bytes

    The Bcrypt standard implementation component has 3 other methods available:

verifyHash() // time-safe verification of a digest against an input (@passwords)
setAlgorithmicCost() // set the algorithmic cost (strength of operation)
getAlgorithmicCost() // get the algorithmic cost (strength of operation)

    This type of component has 3 public constants available:

ALGORITHM_MAXIMUM_OUTPUT // maximum output length in bytes
MINIMUM_ALGORITHMIC_COST // minimum algorithmic cost for computations
MAXIMUM_ALGORITHMIC_COST // maximum algorithmic cost for computations

    The Argon2 standard implementation component has 9 other methods available:

verifyHash() // time-safe verification of a digest against an input (@passwords)
setMemoryCost() // set the memory cost
getMemoryCost() // get the memory cost
setTimeCost() // set the time cost
getTimeCost() // get the time cost
setThreadsCost() // set the thread cost
getThreadsCost() // get the thread cost
setAlgorithmVariation() // set the algorithm version (VERSION_I or VERSION_ID)
getAlgorithmVariation() // get the algorithm version

*Note: The Argon2i is supported in PHP >= 7.2.0 and the Argon2id is supported in PHP >= 7.3.0 (for security reasons).

    This type of component has 3 public constants available:

ALGORITHM_MAXIMUM_OUTPUT // maximum output length in bytes
VERSION_I // Argon2i variation setting
VERSION_ID // Argon2id variation setting

    Here is a simple example for the usage of the PBKDF2 type of hashing component:

use CryptoManana\Hashing\Pbkdf2Sha1;

$hasher = new Pbkdf2Sha1();

$hasher->setDigestFormat($hasher::DIGEST_OUTPUT_HEX_LOWER) // or `Pbkdf2Sha1::`
	->setSaltingMode($hasher::SALTING_MODE_APPEND) // or `Pbkdf2Sha1::`
	->setSalt('hit hard');

$hasher->setDerivationIterations(100000)
	->setOutputLength(20)
	->setDerivationSalt('manana');

$start = microtime(true);

$digest = $hasher->hashData('password');

$end = round((double)microtime(true) - $start, 4);
$end = number_format($end, 4, '.', '');

echo $hasher->verifyHash('password', $digest) ?
    'The passwords match!' : 'The passwords are not the same!';
echo '<br>';

echo 'Text Digest: ' . $digest . '<br>';

echo "Time: $end seconds";

    Here is a simple example for the usage of the Bcrypt type of hashing component:

use CryptoManana\Hashing\Bcrypt;

$hasher = new Bcrypt();

$hasher->setDigestFormat($hasher::DIGEST_OUTPUT_RAW) // or `Bcrypt::`
	->setSaltingMode($hasher::SALTING_MODE_APPEND) // or `Bcrypt::`
	->setSalt('hit hard');

$hasher->setAlgorithmicCost(8);

$start = microtime(true);

$digest = $hasher->hashData('password');

$end = round((double)microtime(true) - $start, 4);
$end = number_format($end, 4, '.', '');

echo $hasher->verifyHash('password', $digest) ?
    'The passwords match!' : 'The passwords are not the same!';
echo '<br>';

echo 'Text Digest: ' . $digest . '<br>';

echo "Time: $end seconds";

    Here is a simple example for the usage of the Argon2 type of hashing component:


use CryptoManana\Hashing\Argon2;

$hasher = new Argon2();

$hasher->setDigestFormat($hasher::DIGEST_OUTPUT_RAW) // or `Argon2::`
	->setSaltingMode($hasher::SALTING_MODE_APPEND) // or `Argon2::`
	->setSalt('hit hard');

// PHP >= 7.3 (or 7.2 for VERSION_I)
$hasher->setAlgorithmVariation($hasher::VERSION_ID)
	->setTimeCost(5)
	->setMemoryCost(1024)
	->setThreadsCost(8);

$start = microtime(true);

$digest = $hasher->hashData('password');

$end = round((double)microtime(true) - $start, 4);
$end = number_format($end, 4, '.', '');

echo $hasher->verifyHash('password', $digest) ?
    'The passwords match!' : 'The passwords are not the same!';
echo '<br>';

echo 'Text Digest: ' . $digest . '<br>';

echo "Time: $end seconds";

Note: Because the configuration here can be tricky, you can use a tool like Kratos to choose a secure one.

The Object Hierarchy

    The internal components’ hierarchy is visualized as a technical diagram and can be seen in Figure 1.

The Hash Function Hierarchy

Figure 1: The data digestion components hierarchy.

    For more information about the capabilities of the components, please see the technical documentation for the \CryptoManana\Hashing namespace.

Previous Next