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");