<?php
/**
* If we encoded (encypted) something using the old Encrypt class,
* and we no longer have mcrypt on the server, we still may need
* to decrypt the data. In that case, this class
* should be able to decrypt the data for us.
*/
defined('BASEPATH') OR exit('No direct script access allowed');
class Legacy_decrypt {
/**
* Initialize class
*/
public function __construct()
{
if( ! function_exists('openssl_decrypt') )
show_error('Legacy_decrypt library requires the OpenSSL extension.');
log_message('info', 'Legacy Decrypt Class Initialized');
}
/**
* Blowfish CBC decryption through OpenSSL, accounting for
* differences in padding between mcrypt and OpenSSL.
*
* @param string the base64 encoded string to decrypt
* @param string the key, which may need to be md5ed
*/
public function blowfish_cbc_decrypt( $base64_encoded, $key )
{
// Ensure data is base64 encoded
if( preg_match('/[^a-zA-Z0-9\/\+=]/', $base64_encoded ) OR base64_encode( base64_decode( $base64_encoded ) ) !== $base64_encoded )
return FALSE;
// Turn the base64 encoded string back into binary data
$pre_noise_removal = base64_decode( $base64_encoded );
// Remove permuted noise from the IV + encrypted data
$cleaned_string = $this->_remove_cipher_noise( $pre_noise_removal, $key );
// Initialization vector for blowfish is 8
$iv_size = 8;
if( $iv_size > strlen( $cleaned_string ) )
return FALSE;
// Get the actual IV that was prepended to the encrypted data
$iv = substr( $cleaned_string, 0, $iv_size );
// Get the actual encrypted data, minus the IV
$encrypted_data = substr( $cleaned_string, $iv_size );
// Decrypt the encrypted data
$str = openssl_decrypt(
$encrypted_data,
'bf-cbc',
$key,
OPENSSL_RAW_DATA | OPENSSL_NO_PADDING,
$iv
);
// Try to detect null padding
if( mb_strlen( $iv, '8bit' ) > 0 && mb_strlen( $iv, '8bit' ) % mb_strlen( $str, '8bit' ) == 0 )
{
preg_match_all( '#([\0]+)$#', $str, $matches );
// If there is null padding
if( mb_strlen( $matches[1][0], '8bit' ) > 1)
{
// Remove the null padding
$str = rtrim($str, "\0");
// Trigger an error so we know there was null padding removed
trigger_error('Detected and stripped null padding. Please double-check results!');
}
}
return rtrim( $str, "\0" );
}
// -----------------------------------------------------------------------
/**
* Removes permuted noise from the IV + encrypted data, reversing
* _add_cipher_noise() that happened in the Encrypt class.
*
* When noise was added to the data, each character was basically
* replaced with an ASCII character, using the key to randomize
* the replacements via ord and chr functions.
*/
private function _remove_cipher_noise($data, $key)
{
$keyhash = sha1( $key );
$keylen = strlen( $keyhash );
$str = '';
for( $i = 0, $j = 0, $len = strlen( $data ); $i < $len; ++$i, ++$j )
{
if( $j >= $keylen )
$j = 0;
$temp = ord( $data[$i] ) - ord( $keyhash[$j] );
if( $temp < 0 )
$temp = $temp + 256;
$str .= chr( $temp );
}
return $str;
}
// -----------------------------------------------------------------------
}
/* End of file Legacy_decrypt.php */
/* Location: /application/libraries/Legacy_decrypt.php */