Encrypting data is security-sensitive. It has led in the past to the following vulnerabilities:

Proper encryption requires both the encryption algorithm and the key to be strong. Obviously the private key needs to remain secret and be renewed regularly. However these are not the only means to defeat or weaken an encryption.

This rule flags function calls that initiate encryption/decryption. The goal is to guide security code reviews.

Ask Yourself Whether

You are at risk if you answered yes to any of those questions.

Recommended Secure Coding Practices

Questionable Code Example

Builtin functions

function myEncrypt($cipher, $key, $data, $mode, $iv, $options, $padding, $infile, $outfile, $recipcerts, $headers, $nonce, $ad, $pub_key_ids, $env_keys)
{
    mcrypt_ecb ($cipher, $key, $data, $mode); // Questionable
    mcrypt_cfb($cipher, $key, $data, $mode, $iv); // Questionable
    mcrypt_cbc($cipher, $key, $data, $mode, $iv); // Questionable
    mcrypt_encrypt($cipher, $key, $data, $mode); // Questionable

    openssl_encrypt($data, $cipher, $key, $options, $iv); // Questionable
    openssl_public_encrypt($data, $crypted, $key, $padding); // Questionable
    openssl_pkcs7_encrypt($infile, $outfile, $recipcerts, $headers); // Questionable
    openssl_seal($data, $sealed_data, $env_keys, $pub_key_ids); // Questionable

    sodium_crypto_aead_aes256gcm_encrypt ($data, $ad, $nonce, $key); // Questionable
    sodium_crypto_aead_chacha20poly1305_encrypt ($data, $ad, $nonce, $key); // Questionable
    sodium_crypto_aead_chacha20poly1305_ietf_encrypt ($data, $ad, $nonce, $key); // Questionable
    sodium_crypto_aead_xchacha20poly1305_ietf_encrypt ($data, $ad, $nonce, $key); // Questionable
    sodium_crypto_box_seal ($data, $key); // Questionable
    sodium_crypto_box ($data, $nonce, $key); // Questionable
    sodium_crypto_secretbox ($data, $nonce, $key); // Questionable
    sodium_crypto_stream_xor ($data, $nonce, $key); // Questionable
}

CakePHP

use Cake\Utility\Security;

function myCakeEncrypt($key, $data, $engine)
{
    Security::encrypt($data, $key); // Questionable

    // Do not use custom made engines and remember that Mcrypt is deprecated.
    Security::engine($engine); // Questionable. Setting the encryption engine.
}

CodeIgniter

class EncryptionController extends CI_Controller
{
    public function __construct()
    {
        parent::__construct();
        $this->load->library('encryption');
    }

    public function index()
    {
        $this->encryption->create_key(16); // Questionable. Review the key length.
        $this->encryption->initialize( // Questionable.
            array(
                'cipher' => 'aes-256',
                'mode' => 'ctr',
                'key' => 'the key',
            )
        );
        $this->encryption->encrypt("mysecretdata"); // Questionable.
    }
}

CraftCMS version 3

use Craft;

// This is similar to Yii as it used by CraftCMS
function craftEncrypt($data, $key, $password) {
    Craft::$app->security->encryptByKey($data, $key); // Questionable
    Craft::$app->getSecurity()->encryptByKey($data, $key); // Questionable
    Craft::$app->security->encryptByPassword($data, $password); // Questionable
    Craft::$app->getSecurity()->encryptByPassword($data, $password); // Questionable
}

Drupal 7 - Encrypt module

function drupalEncrypt() {
    $encrypted_text = encrypt('some string to encrypt'); // Questionable
}

Joomla

use Joomla\Crypt\CipherInterface;

abstract class MyCipher implements CipherInterface // Questionable. Implementing custom cipher class
{}

function joomlaEncrypt() {
    new Joomla\Crypt\Cipher_Sodium(); // Questionable
    new Joomla\Crypt\Cipher_Simple(); // Questionable
    new Joomla\Crypt\Cipher_Rijndael256(); // Questionable
    new Joomla\Crypt\Cipher_Crypto(); // Questionable
    new Joomla\Crypt\Cipher_Blowfish(); // Questionable
    new Joomla\Crypt\Cipher_3DES(); // Questionable
}
}

Laravel

use Illuminate\Support\Facades\Crypt;

function myLaravelEncrypt($data)
{
    Crypt::encryptString($data); // Questionable
    Crypt::encrypt($data); // Questionable
    // encrypt using the Laravel "encrypt" helper
    encrypt($data); // Questionable
}

PHP-Encryption library

use Defuse\Crypto\Crypto;
use Defuse\Crypto\File;

function mypPhpEncryption($data, $key, $password, $inputFilename, $outputFilename, $inputHandle, $outputHandle) {
    Crypto::encrypt($data, $key); // Questionable
    Crypto::encryptWithPassword($data, $password); // Questionable
    File::encryptFile($inputFilename, $outputFilename, $key); // Questionable
    File::encryptFileWithPassword($inputFilename, $outputFilename, $password); // Questionable
    File::encryptResource($inputHandle, $outputHandle, $key); // Questionable
    File::encryptResourceWithPassword($inputHandle, $outputHandle, $password); // Questionable
}

PhpSecLib

function myphpseclib($mode) {
    new phpseclib\Crypt\RSA(); // Questionable. Note: RSA can also be used for signing data.
    new phpseclib\Crypt\AES(); // Questionable
    new phpseclib\Crypt\Rijndael(); // Questionable
    new phpseclib\Crypt\Twofish(); // Questionable
    new phpseclib\Crypt\Blowfish(); // Questionable
    new phpseclib\Crypt\RC4(); // Questionable
    new phpseclib\Crypt\RC2(); // Questionable
    new phpseclib\Crypt\TripleDES(); // Questionable
    new phpseclib\Crypt\DES(); // Questionable

    new phpseclib\Crypt\AES($mode); // Questionable
    new phpseclib\Crypt\Rijndael($mode); // Questionable
    new phpseclib\Crypt\TripleDES($mode); // Questionable
    new phpseclib\Crypt\DES($mode); // Questionable
}

Sodium Compat library

function mySodiumCompatEncrypt($data, $ad, $nonce, $key) {
    ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_ietf_encrypt($data, $ad, $nonce, $key); // Questionable
    ParagonIE_Sodium_Compat::crypto_aead_xchacha20poly1305_ietf_encrypt($data, $ad, $nonce, $key); // Questionable
    ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_encrypt($data, $ad, $nonce, $key); // Questionable

    ParagonIE_Sodium_Compat::crypto_aead_aes256gcm_encrypt($data, $ad, $nonce, $key); // Questionable

    ParagonIE_Sodium_Compat::crypto_box($data, $nonce, $key); // Questionable
    ParagonIE_Sodium_Compat::crypto_secretbox($data, $nonce, $key); // Questionable
    ParagonIE_Sodium_Compat::crypto_box_seal($data, $key); // Questionable
    ParagonIE_Sodium_Compat::crypto_secretbox_xchacha20poly1305($data, $nonce, $key); // Questionable
}

Yii version 2

use Yii;

// Similar to CraftCMS as it uses Yii
function YiiEncrypt($data, $key, $password) {
    Yii::$app->security->encryptByKey($data, $key); // Questionable
    Yii::$app->getSecurity()->encryptByKey($data, $key); // Questionable
    Yii::$app->security->encryptByPassword($data, $password); // Questionable
    Yii::$app->getSecurity()->encryptByPassword($data, $password); // Questionable
}

Zend

use Zend\Crypt\FileCipher;
use Zend\Crypt\PublicKey\DiffieHellman;
use Zend\Crypt\PublicKey\Rsa;
use Zend\Crypt\Hybrid;
use Zend\Crypt\BlockCipher;

function myZendEncrypt($key, $data, $prime, $options, $generator, $lib)
{
    new FileCipher; // Questionable. This is used to encrypt files

    new DiffieHellman($prime, $generator, $key); // Questionable

    $rsa = Rsa::factory([ // Questionable
        'public_key'    => 'public_key.pub',
        'private_key'   => 'private_key.pem',
        'pass_phrase'   => 'mypassphrase',
        'binary_output' => false,
    ]);
    $rsa->encrypt($data); // No issue raised here. The configuration of the Rsa object is the line to review.

    $hybrid = new Hybrid(); // Questionable

    BlockCipher::factory($lib, $options); // Questionable
}

See