Page 1 of 1

openssl_encrypt(): A tag should be provided when using AEAD mode in ...system/library/encryption.php

Posted: Tue Sep 25, 2018 3:50 am
by Different
Good evening everyone!

I am getting a strange warning while trying to buy via credit card. Am using Cardinity payment gateway. OpenCart version 3.0.2.0. PHP version 7.2.0. Quickcheckout by MarketInSG . Here is warning message:

PHP Warning: openssl_encrypt(): Using an empty Initialization Vector (iv) is potentially insecure and not recommended in .../system/library/encryption.php on line 23. My encryption.php looks like this:

Code: Select all

<?php
/**
 * @package		OpenCart
 * @author		Daniel Kerr
 * @copyright	Copyright (c) 2005 - 2017, OpenCart, Ltd. (https://www.opencart.com/)
 * @license		https://opensource.org/licenses/GPL-3.0
 * @link		https://www.opencart.com
*/

/**
* Encryption class
*/
final class Encryption {
	/**
     * 
     *
     * @param	string	$key
	 * @param	string	$value
	 * 
	 * @return	string
     */	
	public function encrypt($key, $value) {
		return strtr(base64_encode(openssl_encrypt($value, 'aes-256-cbc', hash('sha256', $key, true))), '+/=', '-_,');
	}
	
	/**
     * 
     *
     * @param	string	$key
	 * @param	string	$value
	 * 
	 * @return	string
     */
	public function decrypt($key, $value) {
		return trim(openssl_decrypt(base64_decode(strtr($value, '-_,', '+/=')), 'aes-256-cbc', hash('sha256', $key, true)));
	}
}
Then I browsed around forums and found altered encryption.php that looks like this:

Code: Select all

<?php
/**
 * @package		OpenCart
 * @author		Daniel Kerr
 * @copyright	Copyright (c) 2005 - 2017, OpenCart, Ltd. (https://www.opencart.com/)
 * @license		https://opensource.org/licenses/GPL-3.0
 * @link		https://www.opencart.com
*/

/**
* Encryption class
*/
final class Encryption {
	/**
     * 
     *
     * @param	string	$key
	 * @param	string	$value
	 * 
	 * @return	string
     */	
	public function encrypt($key, $value) {
		// Remove the base64 encoding from our key
		$encryption_key = base64_decode($value);
		
		// Generate an initialization vector		
		$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-gcm'));
		
		// Encrypt the data using AES 256 encryption in GCM mode using our encryption key and initialization vector.		
		$encrypted = openssl_encrypt($key, 'aes-256-gcm', $encryption_key, 0, $iv);
		
		// The $iv is just as important as the key for decrypting, so save it with our encrypted data using a unique separator (::)		
		return base64_encode($encrypted . '::' . $iv);
	}
	
	/**
     * 
     *
     * @param	string	$key
	 * @param	string	$value
	 * 
	 * @return	string
     */
	public function decrypt($key, $value) {
		// Remove the base64 encoding from our key
		$encryption_key = base64_decode($value);
		
		// To decrypt, split the encrypted data from our IV - our unique separator used was "::"
		list($encrypted_data, $iv) = explode('::', base64_decode($key), 2);
		
		return openssl_decrypt($encrypted_data, 'aes-256-gcm', $encryption_key, 0, $iv);
	}
}
When I use modified encryption.php file, I get the following warning:

PHP Warning: openssl_encrypt(): A tag should be provided when using AEAD mode in ...system/library/encryption.php on line 30

When you click on button Pay Now, it loads for a couple of seconds and then button is returned back to initial Pay Now state.

Don't know what else to do? To contact hosting company or Cardinity? Any help will be hugely appreciated. Thank you!

Re: openssl_encrypt(): Using an empty Initialization Vector (iv) is potentially insecure and not recommended in system/l

Posted: Tue Sep 25, 2018 5:19 am
by straightlight

Re: openssl_encrypt(): Using an empty Initialization Vector (iv) is potentially insecure and not recommended in system/l

Posted: Tue Sep 25, 2018 5:32 am
by Different
straightlight, if you read my post carefuly, you will see that I have already tried with modified encryption.php file from the topic you linked. It produces this warning message:

Code: Select all

PHP Warning:  openssl_encrypt(): A tag should be provided when using AEAD mode in ...system/library/encryption.php on line 30
Do you have any other idea, or should I contact hosting or Cardinity?

Re: openssl_encrypt(): A tag should be provided when using AEAD mode in ...system/library/encryption.php

Posted: Tue Sep 25, 2018 7:41 pm
by Different
bump

Re: openssl_encrypt(): A tag should be provided when using AEAD mode in ...system/library/encryption.php

Posted: Wed Sep 26, 2018 12:58 am
by IP_CAM
Well, you might try one of the others, from the 3, I know of: ;)
But I guess, that one of them still also uses system/library/bcrypt.php as well,
to make it work, I am just not sure about it. Just to have it mentioned...
Ernie

Code: Select all

<?php
final class Encryption {
	
	private $cipher = 'aes-256-ctr';
	private $digest = 'sha256';
	private $key;
	
	public function __construct($key) {
		$this->key = $key;
	}

	public function encrypt($value) {
		$key       = openssl_digest($this->key, $this->digest, true);
		$iv_length = openssl_cipher_iv_length($this->cipher);
		$iv        = openssl_random_pseudo_bytes($iv_length);
		return base64_encode($iv . openssl_encrypt($value, $this->cipher, $key, OPENSSL_RAW_DATA, $iv));
	}
	
	public function decrypt($value) {
		$key       = openssl_digest($this->key, $this->digest, true);
		$iv_length = openssl_cipher_iv_length($this->cipher);
		$value     = base64_decode($value);
		$iv        = substr($value, 0, $iv_length);
		$value     = substr($value, $iv_length);
		return openssl_decrypt($value, $this->cipher, $key, OPENSSL_RAW_DATA, $iv);
	}
}
---

Code: Select all

<?php
final class Encryption {
	public function encrypt($key, $value) {
		// Remove the base64 encoding from our key
		$encryption_key = base64_decode($value);
		
		// Generate an initialization vector		
		$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-gcm'));
		
		// Encrypt the data using AES 256 encryption in GCM mode using our encryption key and initialization vector.		
		$encrypted = openssl_encrypt($key, 'aes-256-gcm', $encryption_key, 0, $iv);
		
		// The $iv is just as important as the key for decrypting, so save it with our encrypted data using a unique separator (::)		
		return base64_encode($encrypted . '::' . $iv);
	}

	public function decrypt($key, $value) {
		// Remove the base64 encoding from our key
		$encryption_key = base64_decode($value);
		
		// To decrypt, split the encrypted data from our IV - our unique separator used was "::"
		list($encrypted_data, $iv) = explode('::', base64_decode($key), 2);
		
		return openssl_decrypt($encrypted_data, 'aes-256-gcm', $encryption_key, 0, $iv);
	}
}
---

Code: Select all

<?php
final class Encryption {
	private $key;

	public function __construct($key) {
		$this->key = hash('sha256', $key, true);
	}

	public function encrypt($value) {
		$php_version = phpversion();

		if ($php_version >= '7.1') {
			$method = 'AES-128-CBC';

			$iv_length = openssl_cipher_iv_length($method); // 16

			$iv = openssl_random_pseudo_bytes($iv_length);

			$encrypted = openssl_encrypt($value, $method, hash('sha256', $this->key, true), OPENSSL_RAW_DATA, $iv);

		} else {
			$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);

			if ($php_version >= '5.6') {
				$iv = mcrypt_create_iv($iv_size, MCRYPT_DEV_URANDOM);
			} elseif ($php_version >= '5.3') {
				$iv = mcrypt_create_iv($iv_size, MCRYPT_DEV_RANDOM);
			} else {
				$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
			}

			$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, hash('sha256', $this->key, true), $value, MCRYPT_MODE_CBC, $iv);
		}

		$encoded = base64_encode($encrypted) . '|' . base64_encode($iv);

		return strtr($encoded, '+/=', '-_,');
	}

	public function decrypt($value) {
		$php_version = phpversion();

		$value = explode('|', strtr($value, '-_,', '+/=') . '|');

		$decoded = base64_decode($value[0]);

		$iv = base64_decode($value[1]);

		if ($php_version >= '7.1') {
			$method = 'AES-128-CBC';

			$decrypted = trim(openssl_decrypt($decoded, $method, hash('sha256', $this->key, true), OPENSSL_RAW_DATA, $iv));

		} else {
			$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);

			if (strlen($iv) !== $iv_size) {
				return false;
			}

			$decrypted = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, hash('sha256', $this->key, true), $decoded, MCRYPT_MODE_CBC, $iv));
		}

		return $decrypted;
	}
} 

Re: openssl_encrypt(): Using an empty Initialization Vector (iv) is potentially insecure and not recommended in system/l

Posted: Wed Sep 26, 2018 6:50 am
by straightlight
Different wrote:
Tue Sep 25, 2018 5:32 am
straightlight, if you read my post carefuly, you will see that I have already tried with modified encryption.php file from the topic you linked. It produces this warning message:

Code: Select all

PHP Warning:  openssl_encrypt(): A tag should be provided when using AEAD mode in ...system/library/encryption.php on line 30
Do you have any other idea, or should I contact hosting or Cardinity?
Thanks for the feedback. I have now updated the code algorithm to support tagging with cipher when using the aes-256-gcm extension with OpenSSL. Please, try again.

Re: openssl_encrypt(): A tag should be provided when using AEAD mode in ...system/library/encryption.php

Posted: Sat Dec 08, 2018 2:27 am
by Tsaka
I too have exactly the same issue with our store (Using PayPal Pro iFrame) and have now changed the encryption.php file to the new version provided by straightlight (Thanks).

This does fix the issue and no error now comes up, however the card order now goes through fine and the customer eventually then gets redirect to the Checkout Success page as normal. However the payment shows in PayPal but the order never comes through to my opencart shop. It’s as if the order never happened.

I have now reverted back to the old encryption.php file where the error shows but apart from this everything works as normal again
Any ideas?
Thanks

Re: openssl_encrypt(): A tag should be provided when using AEAD mode in ...system/library/encryption.php

Posted: Sun Dec 09, 2018 7:55 am
by ADD Creative
I did point out in that thread that the code posted would never work. You can ignore the warning with the old encryption. However, you should have display errors switched off anyway for a working store. Note, you have to switch off display errors in 3 places to fully switch them off. In settings, in system/config/default.php and in your php.ini files.

PayPal Pro iFrame module only uses it to encrypt the order ID for some reason. Which seems a bit pointless. If you did want to replace the old encryption file with something better. You could try one of the 2 at the link below.
viewtopic.php?f=198&t=204707&p=733515#p737628