diff --git a/QuickBooks/Encryption/AES/Mcrypt.php b/QuickBooks/Encryption/AES/Mcrypt.php new file mode 100755 index 00000000..b14ef0f3 --- /dev/null +++ b/QuickBooks/Encryption/AES/Mcrypt.php @@ -0,0 +1,104 @@ + + * + * @package QuickBooks + */ + +// +QuickBooks_Loader::load('/QuickBooks/Encryption.php'); + +/** + * @brief Mcrypt implementation of AES-256. This method is deprecated since 7.1, + * so it will be selected only if library running < 7.1 and there is mcrypt extension installed. + * Otherwise QuickBooks/Encryption/AES/Openssl.php will be selected + */ +class QuickBooks_Encryption_AES_Mcrypt extends QuickBooks_Encryption +{ + /** + * Encrypt text with specified key + * + * @param string $key Encryption key + * @param string $plain Plain text to be encrypted + * + * @return string + */ + static function encrypt($key, $plain) + { + $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); + } + + $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; + } + + /** + * Decrypt key with specified key + * + * @param string $key Decryption key + * @param string $encrypted Text to be decrypted + * @param bool $with_salt Indicates if we operate with text with salt. If yes - encryption code added some salt, we handle this case. + * + * @see QuickBooks/Encryption/Aes.php + * + * @return string + */ + static function decrypt($key, $encrypted, $with_salt = true) + { + $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 . ']' . '
'); + + $encrypted = base64_decode($encrypted); + + //print('given key was: ' . $key); + //print('iv size: ' . $iv_size); + + //print('decrypting [' . $encrypted . ']' . '
'); + + 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('**]]'); + + if ($with_salt) + { + $tmp = @unserialize($decrypted); + $decrypted = current($tmp); + } + + return $decrypted; + } +} diff --git a/QuickBooks/Encryption/AES/Openssl.php b/QuickBooks/Encryption/AES/Openssl.php new file mode 100644 index 00000000..56f939e3 --- /dev/null +++ b/QuickBooks/Encryption/AES/Openssl.php @@ -0,0 +1,84 @@ + + * + * @package QuickBooks + */ + +// +QuickBooks_Loader::load('/QuickBooks/Encryption.php'); + +/** + * @brief OpenSSL implementation for AES encryption + * + * @author Evgeniy Bogdanov + */ +class QuickBooks_Encryption_AES_Openssl extends QuickBooks_Encryption +{ + const CIPHER = 'aes-256-ecb'; + + /** + * Encrypt text with specified key + * + * @param string $key Encryption key + * @param string $plain Plain text to be encrypted + * + * @return string + */ + static function encrypt($key, $plain) + { + $cipher = self::CIPHER; + + $key = hex2bin(md5($key)); + + $ivlen = openssl_cipher_iv_length($cipher); + $iv = openssl_random_pseudo_bytes($ivlen); + + $encrypted = openssl_encrypt($plain, $cipher, $key, OPENSSL_RAW_DATA, $iv); + $return = base64_encode($iv . $encrypted); + + return $return; + } + + /** + * Decrypt key with specified key + * + * @param string $key Decryption key + * @param string $encrypted Text to be decrypted + * @param bool $with_salt Indicates if we operate with text with salt. If yes - encryption code added some salt, we handle this case + * + * @see QuickBooks/Encryption/Aes.php + * + * @return string + */ + static function decrypt($key, $encrypted, $with_salt = true) + { + $cipher = self::CIPHER; + + $key = hex2bin(md5($key)); + + $decrypted = base64_decode($encrypted); + $ivlen = openssl_cipher_iv_length($cipher); + $iv = substr($decrypted, 0, $ivlen); + + $decrypted = substr($decrypted, $ivlen); + $decrypted = openssl_decrypt($decrypted, $cipher, $key, OPENSSL_RAW_DATA, $iv); + + if ($with_salt) + { + $tmp = @unserialize($decrypted); + $decrypted = current($tmp); + } + + return $decrypted; + } +} diff --git a/QuickBooks/Encryption/Aes.php b/QuickBooks/Encryption/Aes.php old mode 100755 new mode 100644 index 963f5c35..334c206c --- a/QuickBooks/Encryption/Aes.php +++ b/QuickBooks/Encryption/Aes.php @@ -1,87 +1,79 @@ 7.1) + * * Copyright (c) 2010 Keith Palmer / ConsoliBYTE, LLC. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.opensource.org/licenses/eclipse-1.0.php - * - * @author Keith Palmer - * + * + * @author Keith Palmer + * * @package QuickBooks */ -// QuickBooks_Loader::load('/QuickBooks/Encryption.php'); +QuickBooks_Loader::load('/QuickBooks/Encryption/AES/Mcrypt.php'); +QuickBooks_Loader::load('/QuickBooks/Encryption/AES/Openssl.php'); /** - * + * @brief Class is layer to AES encryption. Selects best implementation (Mcrypt or OpenSSL), considering backward compatibility + * + * @author Evgeniy Bogdanov */ -class QuickBooks_Encryption_Aes extends QuickBooks_Encryption +final class QuickBooks_Encryption_AES { - static function encrypt($key, $plain, $salt = null) - { - if (is_null($salt)) - { - $salt = QuickBooks_Encryption::salt(); - } - - $plain = serialize(array( $plain, $salt )); - - $crypt = mcrypt_module_open('rijndael-256', '', 'ofb', ''); + /** + * Encrypts text with specified key + * + * @param string $key Encryption key + * @param string $plain Plain text to be encrypted + * @param string $salt Salt to ba added in encrypted text + * + * @return string + */ + static function encrypt($key, $plain, $salt = null) + { + if (is_null($salt)) + { + $salt = QuickBooks_Encryption::salt(); + } + + $plain = serialize(array( $plain, $salt )); + + return (self::useMCrypt()) + ? QuickBooks_Encryption_AES_Mcrypt::encrypt($key, $plain) + : QuickBooks_Encryption_AES_Openssl::encrypt($key, $plain); + } - 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); - } + /** + * Decrypt key with specified key + * + * @param string $key Decryption key + * @param string $encrypted Text to be decrypted + * @param bool $with_salt Indicates if we operate with text pre-including salt. In most use cases this is true. + * + * @return string + */ + static function decrypt($key, $encrypted, $with_salt = true) + { + return (self::useMCrypt()) + ? QuickBooks_Encryption_AES_Mcrypt::decrypt($key, $encrypted, $with_salt) + : QuickBooks_Encryption_AES_Openssl::decrypt($key, $encrypted, $with_salt); + } - $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; - } - - static function decrypt($key, $encrypted) - { - $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 . ']' . '
'); - - $encrypted = base64_decode($encrypted); - - //print('given key was: ' . $key); - //print('iv size: ' . $iv_size); - - //print('decrypting [' . $encrypted . ']' . '
'); - - 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; - } -} + /** + * Decide if we need o use Mcrypt-way or no + * + * @return bool + */ + static private function useMCrypt() + { + return ( + version_compare(PHP_VERSION, '7.1.0', '<') + && extension_loaded('mcrypt') + ); + } +} \ No newline at end of file diff --git a/QuickBooks/Encryption/Mode/CBC.php b/QuickBooks/Encryption/Mode/CBC.php deleted file mode 100644 index 678a2772..00000000 --- a/QuickBooks/Encryption/Mode/CBC.php +++ /dev/null @@ -1,23 +0,0 @@ - - * @license LICENSE.txt - * - * @package QuickBooks - * @subpackage Encryption - */ - -class QuickBooks_Encryption_Mode_CBC -{ - -} - diff --git a/QuickBooks/Encryption/Mode/ECB.php b/QuickBooks/Encryption/Mode/ECB.php deleted file mode 100644 index ac4502bf..00000000 --- a/QuickBooks/Encryption/Mode/ECB.php +++ /dev/null @@ -1,22 +0,0 @@ - - * @license LICENSE.txt - * - * @package QuickBooks - * @subpackage Encryption - */ - -class QuickBooks_Encryption_Mode_ECB -{ - -} diff --git a/docs/partner_platform/example_app_ipp_v3/troubleshooting.php b/docs/partner_platform/example_app_ipp_v3/troubleshooting.php index 801db9b6..03f24397 100644 --- a/docs/partner_platform/example_app_ipp_v3/troubleshooting.php +++ b/docs/partner_platform/example_app_ipp_v3/troubleshooting.php @@ -51,6 +51,8 @@ } print('php version: ' . phpversion() . "\n"); +print('openssl extension? ' . var_export(extension_loaded('openssl'), true) . "\n"); +print(' openssl module aes-256-ecb ?' . var_export(in_array('aes-256-ecb', openssl_get_cipher_methods()), true) . "\n"); print('mcrypt extension? ' . var_export(function_exists('mcrypt_module_open'), true) . "\n"); print(' mcrypt module rijndael-256? ' . var_export(mcrypt_module_open('rijndael-256', '', 'ofb', ''), true) . "\n"); print('curl extension? ' . var_export(function_exists('curl_init'), true) . "\n");