Symmetric Cryptography
The type of symmetric cryptography, that is also known as secret-key cryptography, defines a security system that uses a single shared secret key (or configuration) to encrypt and decrypt information. The main reason why they are called symmetric is the fact that each operation (encryption/decryption) uses the same single configuration. The symmetric ciphers are widely used for encrypting huge amounts of data that need to be reused or readable by certain parties (in contrast to the one-way hash functions). They are mainly used to encrypt/decrypt network communications, storage devices, sensitive files or payment details. The encrypted data (ciphertext/cipher data) is secure if only the concerned parties have the secret key and the data processing is really fast. There are two main types of ciphers in this category:
- Stream ciphers - Algorithms that process data symbol by symbol and transform it in some matter;
- Block ciphers - Modern ciphers that divide the processing logic into blocks of the original information.
The CryptoMañana (CryptoManana) cryptography framework provides object-oriented components for each of the two types and has a huge set of available realizations.
Basic Methods
The provided software components for symmetrical encryption in the cryptography model always include:
encryptData() // encrypt a string of binary data
decryptData() // decrypt a ciphertext representation
encryptFile() // encrypt a file's content
decryptFile() // decrypt a file's content
encryptObject() // encrypt an object's serialization state
decryptObject() // decrypt an object's serialization state
setSecretKey() // set the secret key
getSecretKey() // get the secret key
setCipherFormat() // set the ciphertext format
getCipherFormat() // get the ciphertext 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).
Ciphertext Format
The software framework supports a vast variety of well-known and frequently used data formats
for the input/output ciphertext value. Each symmetrical encryption object provides 5 formats that can be easily
configured. The specific format can be enabled via the setCipherFormat()
setter method (the default setting
is ENCRYPTION_OUTPUT_BASE_64_URL
) and the available format setting constants per each object. The following options
are available for each component:
ENCRYPTION_OUTPUT_BASE_64_URL
- The raw byte string representation, used by PHP for working with byte arrays (for example�6�a
);ENCRYPTION_OUTPUT_HEX_UPPER
- This is the default format that uses the most popular uppercase HEX representation (for exampleAB45
);ENCRYPTION_OUTPUT_HEX_LOWER
- The lowercase HEX outputting format (for example7f39
);ENCRYPTION_OUTPUT_BASE_64
- The Base64 standard string representation (for exampleB3xGTA==
);ENCRYPTION_OUTPUT_BASE_64_URL
- The Base64 URL friendly string format (for exampleB3xGTA
).
Stream Ciphers
The first supported type is the stream cipher that is important for historical reasons, but is
not as secure as modern block algorithms. This category is mostly used for key transformations (similar to HKDF
functions) or legacy system support. The supported algorithm/standard realizations at the
\CryptoManana\SymmetricEncryption
namespace are:
Rc4
- The RC4-128 encryption algorithm object.
This type of component has 1 public constant available:
KEY_SIZE // The secret key size measured in bytes
Here is a simple example for the usage of this type of encryption component:
use CryptoManana\SymmetricEncryption\Rc4;
use \stdClass as stdClass;
$crypter = new Rc4();
$crypter->setSecretKey('hit hard and run')
->setCipherFormat($crypter::ENCRYPTION_OUTPUT_BASE_64_URL); // or `Rc4::`
$data = 'testing information';
echo 'Data: ' . $data . '<br>';
$cipherData = $crypter->encryptData($data);
echo 'Cipher Data: ' . $cipherData . '<br>';
echo $data === $crypter->decryptData($cipherData) ?
'Data is decrypted successfully' : 'Wrong decryption!';
$object = new stdClass();
$object->data = $data;
$cipherObject = $crypter->encryptObject($object);
echo 'Cipher Object: ' . $cipherObject . '<br>';
$tmp = $crypter->decryptObject($cipherObject);
echo $object->data === $tmp->data ?
'Object is decrypted successfully' : 'Wrong decryption!';
$encryptedContent = $crypter->encryptFile(__FILE__);
$fileName = trim(sys_get_temp_dir()) ?: (string)ini_get('upload_tmp_dir');
$fileName .= DIRECTORY_SEPARATOR . 'testing-file.encrypted';
file_put_contents($fileName, $encryptedContent);
$decryptedContent = $crypter->decryptFile($fileName);
echo file_get_contents(__FILE__) === $decryptedContent ?
'File is decrypted successfully' : 'Wrong decryption!';
@unlink($fileName);
Block Ciphers
The second supported type is the modern type of standard for symmetrical encryption. This
symmetric system requires 3 additional parameters to ensure the division of fixed-size blocks and the data processing is
secure enough. The first one is the initialization vector (IV) that acts as a semantically second key and is used at the
selected mode of operation in some manner. The second parameter is the type the block mode that sets the logic for the
block processing and the connection between certain data values. The final parameter is the padding standard, which
defines the logic used to make the final block long enough to ensure it is the same size as each of the other ones.
Depending on the selected values for the three parameters, the encryption/decryption operation will follow a certain
processing logic that can or can not be run in parallel. For more information, please look up
the Block cipher mode of operation Wikipedia page
(or other cryptography literature, etc.). The supported algorithm/standard realizations at the
\CryptoManana\SymmetricEncryption
namespace are:
Aes128
- The AES-128 symmetrical encryption object;Aes192
- The AES-192 symmetrical encryption object;Aes256
- The AES-256 symmetrical encryption object;Camellia128
- The CAMELLIA-128 symmetrical encryption object;Camellia192
- The CAMELLIA-192 symmetrical encryption object;Camellia256
- The CAMELLIA-256 symmetrical encryption object;TripleDes
- The 3DES-168 (T-DES) symmetrical encryption object.
It is important to mention that the block cipher components have 6 other methods available:
setInitializationVector() // set the initialization vector
getInitializationVector() // get the initialization vector
setBlockOperationMode() // set the block operation mode
getBlockOperationMode() // get the block operation mode
setPaddingStandard() // set the padding standard
getPaddingStandard() // get the padding standard
This type of component has 1 public constant available:
KEY_SIZE // The secret key size measured in bytes
IV_SIZE // The initialization vector measured in bytes
BLOCK_SIZE // The internal block size measured in bytes
Each symmetrical block encryption object provides 5 modes of operation that can be easily
configured. The specific mode can be enabled via the setBlockOperationMode()
setter method (the default setting
is CBC_MODE
) and the available setting constants per each object. The framework supports the following block operation
modes for encryption/decryption:
CBC_MODE
- The Cipher Block Chaining (CBC) mode of operation, this is the default mode;CFB_MODE
- The Cipher Feedback (CFB) mode of operation;OFB_MODE
- The Output Feedback (OFB) mode of operation;CTR_MODE
- The Counter (CTR) mode of operation (not supported byTripleDes
);ECB_MODE
- The Electronic Codebook (ECB).
The symmetrical block encryption object provides 2 padding standards that can be easily
configured. The specific padding mode can be enabled via the setPaddingStandard()
setter method (the default setting
is PKCS7_PADDING
) and the available setting constants per each object. The framework supports the following final
block padding modes for encryption/decryption:
ZERO_PADDING
- The zero-padding (non-standard);PKCS7_PADDING
- The PKCS#7 (Cryptographic Message Syntax Standard) padding, this is the default padding.
Here is a simple example for the usage of this type of encryption component:
use CryptoManana\SymmetricEncryption\Aes256;
use \stdClass as stdClass;
$crypter = new Aes256();
$crypter->setSecretKey('hit hard and run')
->setInitializationVector('run hard and hit')
->setCipherFormat($crypter::ENCRYPTION_OUTPUT_BASE_64_URL); // or `Aes256::`
$crypter->setBlockOperationMode($crypter::CFB_MODE) // or `Aes256::`
->setPaddingStandard($crypter::PKCS7_PADDING); // or `Aes256::`
$data = 'testing information';
echo 'Data: ' . $data . '<br>';
$cipherData = $crypter->encryptData($data);
echo 'Cipher Data: ' . $cipherData . '<br>';
echo $data === $crypter->decryptData($cipherData) ?
'Data is decrypted successfully' : 'Wrong decryption!';
$object = new stdClass();
$object->data = $data;
$cipherObject = $crypter->encryptObject($object);
echo 'Cipher Object: ' . $cipherObject . '<br>';
$tmp = $crypter->decryptObject($cipherObject);
echo $object->data === $tmp->data ?
'Object is decrypted successfully' : 'Wrong decryption!';
$encryptedContent = $crypter->encryptFile(__FILE__);
$fileName = trim(sys_get_temp_dir()) ?: (string)ini_get('upload_tmp_dir');
$fileName .= DIRECTORY_SEPARATOR . 'testing-file.encrypted';
file_put_contents($fileName, $encryptedContent);
$decryptedContent = $crypter->decryptFile($fileName);
echo file_get_contents(__FILE__) === $decryptedContent ?
'File is decrypted successfully' : 'Wrong decryption!';
@unlink($fileName);
The Object Hierarchy
The internal components’ hierarchy is visualized as a technical diagram and can be seen in Figure 1.
Figure 1: The data symmetric encryption components hierarchy.
For more information about the capabilities of the components, please see the technical
documentation for
\CryptoManana\SymmetricEncryption
namespace.