Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(mcrypt deprecation): removing references to mcrypt going forward #309

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 18 additions & 7 deletions QuickBooks/Encryption.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
*/
abstract class QuickBooks_Encryption
{
const CIPHER = 'aes-256-cfb';

/**
*
*
Expand All @@ -46,12 +48,21 @@ public function prefix($str)
*/
static function salt()
{
$tmp = array_merge(range('a', 'z'), range('A', 'Z'), range(0, 9));
shuffle($tmp);

$salt = substr(implode('', $tmp), 0, 32);

return $salt;
}
return self::iv();
}

/**
* Create an initialization vector to be used with our encryption algorithm
*
* @return string
*/

static function iv()
{
$ivlen = openssl_cipher_iv_length(self::CIPHER);
$iv = openssl_random_pseudo_bytes($ivlen);

return $iv;
}
}

137 changes: 82 additions & 55 deletions QuickBooks/Encryption/Aes.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php

/**
* AES Encryption (depends on mcrypt for now)
* AES Encryption
*
* Copyright (c) 2010 Keith Palmer / ConsoliBYTE, LLC.
* All rights reserved. This program and the accompanying materials
Expand All @@ -22,66 +22,93 @@
*/
class QuickBooks_Encryption_Aes extends QuickBooks_Encryption
{
static function encrypt($key, $plain, $salt = null)
/**
* Encrypt a plaintext string using openssl and the algorithm in self::CIPHER
*
* @param string $key The passphrase for the encryption algorithm
* @param string $plain The plaintext to be encrypted
* @param string $iv The initialization vector for the encryption algorithm
*
* @return false|string
*/
static function encrypt($key, $plain, $iv = null)
{
if (is_null($salt))
if (is_null($iv))
{
$salt = QuickBooks_Encryption::salt();
$iv = QuickBooks_Encryption::iv();
}

$plain = serialize(array( $plain, $salt ));

$crypt = mcrypt_module_open('rijndael-256', '', 'ofb', '');

if (false !== stripos(PHP_OS, 'win') and
version_compare(PHP_VERSION, '5.3.0') == -1)
{
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($crypt), MCRYPT_RAND);
}
else
{
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($crypt), MCRYPT_DEV_URANDOM);
}
// Encrypt the plaintext
$encrypted = openssl_encrypt($plain, self::CIPHER, $key, OPENSSL_RAW_DATA, $iv);
// Create a hmac hash to compare when we're decrypting
$encrypted_hmac = hash_hmac('sha256', $encrypted, $key, true);
// Include the hmac and encode
$encrypted_encoded = base64_encode($encrypted_hmac . $encrypted);
// Prepend this string, so we know how we need to decrypt ( mcrypt(deprecated) vs. openssl )
$final_encrypted = 'openssl:' . $encrypted_encoded;

$ks = mcrypt_enc_get_key_size($crypt);
$key = substr(md5($key), 0, $ks);

mcrypt_generic_init($crypt, $key, $iv);
$encrypted = base64_encode($iv . mcrypt_generic($crypt, $plain));
mcrypt_generic_deinit($crypt);
mcrypt_module_close($crypt);

return $encrypted;
}
return $final_encrypted;
}

static function decrypt($key, $encrypted)
static function decrypt($key, $raw_encrypted, $iv = null)
{
$crypt = mcrypt_module_open('rijndael-256', '', 'ofb', '');
$iv_size = mcrypt_enc_get_iv_size($crypt);
$ks = mcrypt_enc_get_key_size($crypt);
$key = substr(md5($key), 0, $ks);

//print('before base64 [' . $encrypted . ']' . '<br />');

$encrypted = base64_decode($encrypted);

//print('given key was: ' . $key);
//print('iv size: ' . $iv_size);

//print('decrypting [' . $encrypted . ']' . '<br />');

mcrypt_generic_init($crypt, $key, substr($encrypted, 0, $iv_size));
$decrypted = trim(mdecrypt_generic($crypt, substr($encrypted, $iv_size)));
mcrypt_generic_deinit($crypt);
mcrypt_module_close($crypt);

//print('decrypted: [[**(' . $salt . ')');
//print_r($decrypted);
//print('**]]');

$tmp = unserialize($decrypted);
$decrypted = current($tmp);

return $decrypted;
if (is_null($iv))
{
return false;
}

if (strpos($raw_encrypted, 'openssl:') === 0) // decrypt using openssl
{
// remove the openssl tag
$encrypted = substr($raw_encrypted, 8);
// Decode
$decoded_encrypted = base64_decode($encrypted);
// Remove the hmac
$sha2len = 32;
$hmac = substr($decoded_encrypted, 0, $sha2len);
$encrypted_raw = substr($decoded_encrypted, $sha2len);

$decrypted = openssl_decrypt($encrypted_raw, self::CIPHER, $key, OPENSSL_RAW_DATA, $iv);

$calcmac = hash_hmac('sha256', $encrypted_raw, $key, true);
if (hash_equals($hmac, $calcmac))// timing attack safe comparison
{
return $decrypted;
}
}
else
{

// This is deprecated
$crypt = @mcrypt_module_open('rijndael-256', '', 'ofb', '');
$iv_size = @mcrypt_enc_get_iv_size($crypt);
$ks = @mcrypt_enc_get_key_size($crypt);
$key = substr(md5($key), 0, $ks);

//print('before base64 [' . $encrypted . ']' . "\n");

$encrypted = base64_decode($raw_encrypted);

//print('given key was: ' . $key);
//print('iv size: ' . $iv_size);

//print('decrypting [' . $encrypted . ']' . '<br />');

@mcrypt_generic_init($crypt, $key, substr($encrypted, 0, $iv_size));
$decrypted = trim(@mdecrypt_generic($crypt, substr($encrypted, $iv_size)));
@mcrypt_generic_deinit($crypt);
@mcrypt_module_close($crypt);

//print('decrypted: [[**(' . $salt . ')');
//print_r($decrypted);
//print('**]]');

$tmp = unserialize($decrypted);
$decrypted = current($tmp);

return $decrypted;
}

return false;
}
}