Encryption/Decryption

Phalcon provides encryption facilities via the Phalcon\Crypt component. This class offers simple object-oriented wrappers to the openssl PHP’s encryption library.

By default, this component provides secure encryption using AES-256-CFB.

The cipher AES-256 is used among other places in SSL/TLS across the Internet. It’s considered among the top ciphers. In theory it’s not crackable since the combinations of keys are massive. Although NSA has categorized this in Suite B, they have also recommended using higher than 128-bit keys for encryption.

You must use a key length corresponding to the current algorithm. For the algorithm used by default it is 32 bytes.

Basic Usage

This component is designed be very simple to use:

  1. <?php
  2. use Phalcon\Crypt;
  3. // Create an instance
  4. $crypt = new Crypt();
  5. /**
  6. * Set the cipher algorithm.
  7. *
  8. * The `aes-256-gcm' is the preferable cipher, but it is not usable until the
  9. * openssl library is upgraded, which is available in PHP 7.1.
  10. *
  11. * The `aes-256-ctr' is arguably the best choice for cipher
  12. * algorithm in these days.
  13. */
  14. $crypt->setCipher('aes-256-ctr');
  15. /**
  16. * Set the encryption key.
  17. *
  18. * The `$key' should have been previously generated in a cryptographically safe way.
  19. *
  20. * Bad key:
  21. * "le password"
  22. *
  23. * Better (but still unsafe):
  24. * "#1dj8$=dp?.ak//j1V$~%*0X"
  25. *
  26. * Good key:
  27. * "T4\xb1\x8d\xa9\x98\x05\\\x8c\xbe\x1d\x07&[\x99\x18\xa4~Lc1\xbeW\xb3"
  28. *
  29. * Use your own key. Do not copy and paste this example key.
  30. */
  31. $key = "T4\xb1\x8d\xa9\x98\x05\\\x8c\xbe\x1d\x07&[\x99\x18\xa4~Lc1\xbeW\xb3";
  32. $text = 'This is the text that you want to encrypt.';
  33. $encrypted = $crypt->encrypt($text, $key);
  34. echo $crypt->decrypt($encrypted, $key);

You can also set the algorithm and whether to calculate a digest of the message (signing) during the object construction. This removes the need to call setCipher() and useSigning():

  1. <?php
  2. use Phalcon\Crypt;
  3. // Create an instance
  4. $crypt = new Crypt('aes-256-ctr', true);
  5. $key = "T4\xb1\x8d\xa9\x98\x05\\x8c\xbe\x1d\x07&[\x99\x18\xa4~Lc1\xbeW\xb3";
  6. $text = 'This is the text that you want to encrypt.';
  7. $encrypted = $crypt->encrypt($text, $key);
  8. echo $crypt->decrypt($encrypted, $key);

You can use the same instance to encrypt/decrypt several times:

  1. <?php
  2. use Phalcon\Crypt;
  3. // Create an instance
  4. $crypt = new Crypt();
  5. $crypt->setCipher('aes-256-ctr');
  6. // Use your own keys!
  7. $texts = [
  8. "T4\xb1\x8d\xa9\x98\x054t7w!z%C*F-Jk\x98\x05\\\x5c" => 'This is a secret text',
  9. "T4\xb1\x8d\xa9\x98\x05\\\x8c\xbe\x1d\x07&[\x99\x18\xa4~Lc1\xbeW\xb3" => 'This is a very secret',
  10. ];
  11. foreach ($texts as $key => $text) {
  12. // Perform the encryption
  13. $encrypted = $crypt->encrypt($text, $key);
  14. // Now decrypt
  15. echo $crypt->decrypt($encrypted, $key);
  16. }

For better security, you can instruct the component to calculate a message digest based on one of the supported algorithms returned by getAvailableHashAlgos. As seen above this algorithm can be set during the object instantiation but can also be set afterwards.

NOTE Calculating the message digest (signing) will be enabled by default in Phalcon 4.0.0 or greater.

  1. <?php
  2. use Phalcon\Crypt;
  3. // Create an instance
  4. $crypt = new Crypt();
  5. $crypt->setCipher('aes-256-ctr');
  6. $crypt->setHashAlgo('aes-256-cfb');
  7. // Force calculation of a digest of the message based on the Hash algorithm
  8. $crypt->useSigning(true);
  9. $key = "T4\xb1\x8d\xa9\x98\x054t7w!z%C*F-Jk\x98\x05\\x5c";
  10. $text = 'This is a secret text';
  11. // Perform the encryption
  12. $encrypted = $crypt->encrypt($text, $key);
  13. // Now decrypt
  14. echo $crypt->decrypt($encrypted, $key);

Encryption Options

The following options are available to change the encryption behavior:

NameDescription
CipherThe cipher is one of the encryption algorithms supported by openssl. You can see a list here

Example:

  1. <?php
  2. use Phalcon\Crypt;
  3. // Create an instance
  4. $crypt = new Crypt();
  5. // Use blowfish
  6. $crypt->setCipher('bf-cbc');
  7. // Use your own key!
  8. $key = "T4\xb1\x8d\xa9\x98\x05\\\x8c\xbe\x1d\x07&[\x99\x18\xa4~Lc1\xbeW\xb3";
  9. $text = 'This is a secret text';
  10. echo $crypt->encrypt($text, $key);

If you wish to check the available algorithms that your system supports you can call the getAvailableHashAlgos() method.

  1. <?php
  2. use Phalcon\Crypt;
  3. // Create an instance
  4. $crypt = new Crypt();
  5. // Get the supported algorithms
  6. $algorithms = $crypt->getAvailableHashAlgos();
  7. var_dump($algorithms);

Base64 Support

In order for encryption to be properly transmitted (emails) or displayed (browsers) base64 encoding is usually applied to encrypted texts:

  1. <?php
  2. use Phalcon\Crypt;
  3. // Create an instance
  4. $crypt = new Crypt();
  5. // Use your own key!
  6. $key = "T4\xb1\x8d\xa9\x98\x05\\\x8c\xbe\x1d\x07&[\x99\x18\xa4~Lc1\xbeW\xb3";
  7. $text = 'This is a secret text';
  8. $encrypt = $crypt->encryptBase64($text, $key);
  9. echo $crypt->decryptBase64($encrypt, $key);

Setting up an Encryption service

You can set up the encryption component in the services container in order to use it from any part of the application:

  1. <?php
  2. use Phalcon\Crypt;
  3. $di->set(
  4. 'crypt',
  5. function () {
  6. $crypt = new Crypt();
  7. // Set a global encryption key
  8. $crypt->setKey(
  9. "T4\xb1\x8d\xa9\x98\x05\\\x8c\xbe\x1d\x07&[\x99\x18\xa4~Lc1\xbeW\xb3"
  10. );
  11. return $crypt;
  12. },
  13. true
  14. );

Then, for example, in a controller you can use it as follows:

  1. <?php
  2. use Phalcon\Mvc\Controller;
  3. class SecretsController extends Controller
  4. {
  5. public function saveAction()
  6. {
  7. $secret = new Secrets();
  8. $text = $this->request->getPost('text');
  9. $secret->content = $this->crypt->encrypt($text);
  10. if ($secret->save()) {
  11. $this->flash->success(
  12. 'Secret was successfully created!'
  13. );
  14. }
  15. }
  16. }