Saturday, November 24, 2012

AES php Example CBC, 128bit, PKCS7

Understanding the AES Decryption Class

The provided PHP class is an implementation of AES encryption and decryption using the AES-CBC (Cipher Block Chaining) mode with RIJNDAEL_128 and PKCS7 padding. This class is primarily focused on decryption and offers a structured way to handle AES-related operations, including key and IV management and the unpadding of decrypted data.


CLASS

class aes {
 
    protected $mcrypt_cipher = MCRYPT_RIJNDAEL_128;
    protected $mcrypt_mode = MCRYPT_MODE_CBC;
 
    private $_key;
    private $_iv;
 
    public function __construct($key, $iv)
 {
        self::setKey($key);
        self::setIV($iv);
    }
 
    public function setKey($key)
    {
        $this->_key = base64_decode($key);
 
    }
 
    public function setIV($iv)
    {
        $this->_iv = base64_decode($iv);
    }
 
    public function decrypt ($value)
    {
        if ( is_null ($value) ) $value = "" ;
        $value = base64_decode ($value);
        $output = mcrypt_decrypt($this->mcrypt_cipher, $this->_key, $value, $this->mcrypt_mode, $this->_iv);
 
        return self::unpadPkcs7($output, strlen($output));
    }
 
    function unpadPkcs7($text, $blocksize) {
        if (empty($text)) {
            return '';
        }
 
        if (strlen($text) % $blocksize !== 0) {
            return false;
        }
 
        $pad = ord($text{strlen($text)-1});
 
        if ($pad > $blocksize || $pad > strlen($text) || $pad === 0) {
            return false;
        }
        if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) {
            return false;
        }
        return substr($text, 0, - $pad);
    }
}

Usage

$aesClass = new aes('key', 'iv');
$decrypted = $aesClass->decrypt(urldecode($token));


Class Breakdown

1. Properties

  • $mcrypt_cipher: Defines the encryption cipher, set to MCRYPT_RIJNDAEL_128, which is a specific implementation of AES.
  • $mcrypt_mode: Defines the cipher mode, set to MCRYPT_MODE_CBC (Cipher Block Chaining).
  • $_key: Stores the decoded encryption key.
  • $_iv: Stores the decoded initialization vector (IV).

2. Constructor

The constructor initializes the class by setting the encryption key and IV:

public function __construct($key, $iv)
  • setKey: Decodes the base64-encoded key and stores it.
  • setIV: Decodes the base64-encoded IV and stores it.

3. Methods

setKey($key)

This method decodes a base64-encoded key string and assigns it to the internal _key property.

setIV($iv)

This method decodes a base64-encoded IV string and assigns it to the internal _iv property.

decrypt($value)

The main method for decryption:

  1. Decodes the input ciphertext (assumed to be base64-encoded).
  2. Uses the mcrypt_decrypt() function to decrypt the data with the provided cipher, mode, key, and IV.
  3. Removes the PKCS7 padding from the decrypted output using the helper method unpadPkcs7.
unpadPkcs7($text, $blocksize)

Handles the removal of PKCS7 padding from the decrypted plaintext:

  • Ensures that the padding is valid by checking:
    1. The length of the padding.
    2. The padding value consistency across the padded bytes.
  • If the padding is valid, it removes it. Otherwise, it returns false.

Example Usage

$aesClass = new aes('key', 'iv');  // Replace 'key' and 'iv' with base64-encoded strings
$decrypted = $aesClass->decrypt(urldecode($token));  // Decrypt the provided token
  • key: Base64-encoded AES key.
  • iv: Base64-encoded AES initialization vector.
  • $token: The base64-encoded ciphertext that needs to be decrypted.

Key Features

  1. CBC Mode: Ensures enhanced security by using an IV, making identical plaintexts result in different ciphertexts.
  2. Base64 Handling: Assumes all inputs (key, IV, and ciphertext) are base64-encoded, ensuring compatibility with web-based tools.
  3. PKCS7 Padding: Handles decryption of padded data securely and verifies the integrity of the padding.
  4. Error Handling: Returns false if decryption fails or if the padding is invalid.

Limitations

  1. Deprecated mcrypt Library:
    The mcrypt library is deprecated in modern PHP versions (7.1 and later). Consider replacing it with openssl for future-proofing.

  2. No Encryption Support:
    The class only supports decryption. If encryption is required, additional methods need to be implemented.

  3. Base64 Assumption:
    The class assumes all inputs are base64-encoded, which might not always be the case depending on the source of the data.


Modern Alternative

For newer PHP versions, replace mcrypt_decrypt with openssl_decrypt. Example:

$output = openssl_decrypt($value, 'aes-128-cbc', $this->_key, OPENSSL_RAW_DATA, $this->_iv);


Web AES Tool

The code is compatible with tools like the https://www.txtwizard.net/encryption, making it easy to test and verify encryption/decryption results.

By using this class, developers can easily decrypt AES-encrypted data with minimal setup, provided they have the correct key and IV.