Post by daveydave » Mon May 28, 2018 7:04 pm

Hi,

I'm setting up Paypal Pro Iframe (redirect) on a shop site and get this error when I attempt to put a test payment through:

Warning: openssl_encrypt(): Using an empty Initialization Vector (iv) is potentially insecure and not recommended in /home/site/public_html/system/library/encryption.php on line 23


I've googled this error and nobody else seems to have experienced it on OpenCart 3.0.2.0, so I can only assume I've set up my server incorrectly to work with this plugin. Has anyone got any idea what the problem may be?

New member

Posts

Joined
Fri Aug 28, 2015 10:26 pm

Post by straightlight » Tue May 29, 2018 3:08 am


The most generated errors being found on Opencart forum originates from contributed programming. The increased counters are caused by posted redundancies of the same solutions that were already provided prior.

F. Rules:

- viewtopic.php?f=176&t=200480
- viewtopic.php?f=176&t=200804


Regards,
Straightlight


Legendary Member

Posts

Joined
Mon Nov 14, 2011 11:38 pm
Location - Canada, ON

Post by daveydave » Tue May 29, 2018 5:07 am

I saw that post. I'm already running PHP 7

New member

Posts

Joined
Fri Aug 28, 2015 10:26 pm

Post by straightlight » Tue May 29, 2018 11:21 pm

An interesting concept I may have found on this site: https://bhoover.com/using-php-openssl_e ... rypt-data/ since Opencart also uses the openssl random pseudo bytes as an encryption method.

See if by replacing your entire system/library/encryption.php file will solve the issue with these modifications:

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.
		if (in_array('aes-256-gcm', openssl_get_cipher_methods())) {
		    $tag = base64_encode($iv);
		    
		    $encrypted = openssl_encrypt($key, 'aes-256-gcm', $encryption_key, 0, $iv, $tag);		   
		    
		    // 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) {
	       if (in_array('aes-256-gcm', openssl_get_cipher_methods())) {
		    // 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);
		    
		    $tag = base64_decode($iv);
		    
		    return openssl_decrypt($encrypted_data, 'aes-256-gcm', $encryption_key, 0, $iv, $tag);
	      }
       }
}
Update: According to this site: https://security.stackexchange.com/ques ... ion-vector , it would seem using the CBC algorithm may not be as secured either. Using the GCM algorithm may be more secured. Codes above have been modified accordingly.

Added a tag encoding method with the compression algorithm. Source: https://stackoverflow.com/questions/519 ... -tag-value


Then, ensure to follow these steps before testing your store: viewtopic.php?f=176&p=721388#p718325 . Since this procedure is also about modifying encryption and decryption methods, better to make a backup of your entire store as well.
Last edited by straightlight on Wed Sep 26, 2018 6:52 am, edited 4 times in total.

The most generated errors being found on Opencart forum originates from contributed programming. The increased counters are caused by posted redundancies of the same solutions that were already provided prior.

F. Rules:

- viewtopic.php?f=176&t=200480
- viewtopic.php?f=176&t=200804


Regards,
Straightlight


Legendary Member

Posts

Joined
Mon Nov 14, 2011 11:38 pm
Location - Canada, ON

Post by daveydave » Sat Jun 02, 2018 5:34 pm

Thanks for this. It seems to work.
Sorry for the late reply, after this started working, Paypal started generating errors so I needed to communicate with their tech support department.

New member

Posts

Joined
Fri Aug 28, 2015 10:26 pm

Post by straightlight » Sat Jun 02, 2018 7:34 pm

Outstanding. Thanks for confirming this. I will address this solution on GitHub since this issue seem to be related to untested OpenSSL length even though, in the past on the forum, it has been discussed that programmers needs to ensure that the vector's parameter is properly defined. From now on, this should no longer be a concern other than viewing the logs when testing transactions.

The most generated errors being found on Opencart forum originates from contributed programming. The increased counters are caused by posted redundancies of the same solutions that were already provided prior.

F. Rules:

- viewtopic.php?f=176&t=200480
- viewtopic.php?f=176&t=200804


Regards,
Straightlight


Legendary Member

Posts

Joined
Mon Nov 14, 2011 11:38 pm
Location - Canada, ON

Post by straightlight » Sun Sep 02, 2018 9:55 pm

The code above has now been updated with GCM rather than CBC algorithm in accordance of the RFC standards.

The most generated errors being found on Opencart forum originates from contributed programming. The increased counters are caused by posted redundancies of the same solutions that were already provided prior.

F. Rules:

- viewtopic.php?f=176&t=200480
- viewtopic.php?f=176&t=200804


Regards,
Straightlight


Legendary Member

Posts

Joined
Mon Nov 14, 2011 11:38 pm
Location - Canada, ON

Post by straightlight » Wed Sep 26, 2018 6:53 am

Algorithm updated above now supporting tagging with cipher validation related with OpenSSL when using ZIP compression.

The most generated errors being found on Opencart forum originates from contributed programming. The increased counters are caused by posted redundancies of the same solutions that were already provided prior.

F. Rules:

- viewtopic.php?f=176&t=200480
- viewtopic.php?f=176&t=200804


Regards,
Straightlight


Legendary Member

Posts

Joined
Mon Nov 14, 2011 11:38 pm
Location - Canada, ON

Post by ADD Creative » Wed Oct 17, 2018 10:32 pm

straightlight wrote:
Tue May 29, 2018 11:21 pm

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.
 if (in_array('aes-256-gcm', openssl_get_cipher_methods())) {
 $tag = base64_encode($iv);
 
 $encrypted = openssl_encrypt($key, 'aes-256-gcm', $encryption_key, 0, $iv, $tag); 
 
 // 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) {
 if (in_array('aes-256-gcm', openssl_get_cipher_methods())) {
 // 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);
 
 $tag = base64_decode($iv);
 
 return openssl_decrypt($encrypted_data, 'aes-256-gcm', $encryption_key, 0, $iv, $tag);
 }
 }
}
There are a few errors in the code posted. Firstly in encrypt you are creating the key from the data to be encrypted and using it to encrypt the key (neither of which will be base64 encoded). openssl_cipher_iv_length('aes-256-gcm') is used in before the test that 'aes-256-gcm' is available.

Again in decrypt you are trying to decrypt the key using the data as a key.

The line '$tag = base64_decode($iv);' is wrong in both encrypt and decrypt. The $tag should be the one generated from openssl_encrypt (passed by reference).

Even if the data and key were correct. How can you be sure '::' won't appear in the IV?

Also note you would need PHP 7.1 or greater to use $tag.

At least have a look at: Example 1 at http://php.net/manual/en/function.openssl-encrypt.php Although don't assune the example is suitble for actual use.

On PHP 7.2 sodium_crypto_secretbox is probably a better option and there is less to get wrong. Just a shame not all hosts are including it.

ADD Creative - Web development and e-commerce development, Milton Keynes or Christchurch, UK
ADD Filtration - HVAC Panel Filters, Bag Filters and HEPA Filters


Active Member

Posts

Joined
Sat Jan 14, 2012 1:02 am

Post by straightlight » Sun Oct 21, 2018 1:14 am

Also note you would need PHP 7.1 or greater to use $tag.
Which is exactly why the OC team requires PHP v7.1 as a minimum requirement to operate OC starting on their next release.

The most generated errors being found on Opencart forum originates from contributed programming. The increased counters are caused by posted redundancies of the same solutions that were already provided prior.

F. Rules:

- viewtopic.php?f=176&t=200480
- viewtopic.php?f=176&t=200804


Regards,
Straightlight


Legendary Member

Posts

Joined
Mon Nov 14, 2011 11:38 pm
Location - Canada, ON

Post by ADD Creative » Sun Oct 21, 2018 4:17 am

The code you posted still wouldn't work even if you were using PHP 7.1. Have you tested it?

ADD Creative - Web development and e-commerce development, Milton Keynes or Christchurch, UK
ADD Filtration - HVAC Panel Filters, Bag Filters and HEPA Filters


Active Member

Posts

Joined
Sat Jan 14, 2012 1:02 am

Post by straightlight » Sun Oct 21, 2018 5:34 am

It does work. You just need to have the GCM extension installed rather than the CBC extension. However, since new SSL functions seem to be involved on PHP v7.2x and that mcrypt algorithms have been deprecated, better to wait for the OC team to set the minimum requirements to PHP v7.2 in this case. However, the provided solution will work until the new requirements comes in.

The most generated errors being found on Opencart forum originates from contributed programming. The increased counters are caused by posted redundancies of the same solutions that were already provided prior.

F. Rules:

- viewtopic.php?f=176&t=200480
- viewtopic.php?f=176&t=200804


Regards,
Straightlight


Legendary Member

Posts

Joined
Mon Nov 14, 2011 11:38 pm
Location - Canada, ON

Post by ADD Creative » Sun Oct 21, 2018 6:04 am

It doesn't work and there is no way it could work, as I described in the few posts above.

ADD Creative - Web development and e-commerce development, Milton Keynes or Christchurch, UK
ADD Filtration - HVAC Panel Filters, Bag Filters and HEPA Filters


Active Member

Posts

Joined
Sat Jan 14, 2012 1:02 am

Post by ADD Creative » Sun Oct 21, 2018 7:02 am

Here are two basic examples on replacing the encryption in OpenCart 3.0.2.0. Probably need to add checks on the length of the value to decrypt and some checks that the functions exist. Done a basic test, but recommend to add checks and test fully before using.

For PHP 7.2 as long as host has correctly included sodium (check with phpinfo and ask host if it isn't there).

Code: Select all

<?php
final class Encryption {
	public function encrypt($key, $value) {
		$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);

		return strtr(base64_encode($nonce . sodium_crypto_secretbox($value, $nonce, hash('sha256', $key, true))), '+/=', '-_,');
	}

	public function decrypt($key, $value) {
		$raw_value = base64_decode(strtr($value, '-_,', '+/='));

		$nonce = substr($raw_value, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);

		return trim(sodium_crypto_secretbox_open(substr($raw_value, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES), $nonce, hash('sha256', $key, true)));
	}
}
?>

For PHP 7.1 using openssl 'aes-256-gcm'.

Code: Select all

<?php
final class Encryption {
	public function encrypt($key, $value) {
		$key = $this->key;

		$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-gcm'));

		$tag = '';

		$encrypted = openssl_encrypt($value, 'aes-256-gcm', hash('sha256', $key, true), OPENSSL_RAW_DATA, $iv, $tag);
 
		return strtr(base64_encode($iv . $tag . $encrypted), '+/=', '-_,');
	}

	public function decrypt($key, $value) {
		$key = $this->key;

		$encrypted = base64_decode(strtr($value, '-_,', '+/='));

		$iv_len = openssl_cipher_iv_length('aes-256-gcm');

		$iv = substr($encrypted, 0, $iv_len);

		$tag = substr($encrypted, $iv_len, 16);

		return trim(openssl_decrypt(substr($encrypted, $iv_len + 16), 'aes-256-gcm', hash('sha256', $key, true), OPENSSL_RAW_DATA, $iv, $tag));
	}
}
?>

ADD Creative - Web development and e-commerce development, Milton Keynes or Christchurch, UK
ADD Filtration - HVAC Panel Filters, Bag Filters and HEPA Filters


Active Member

Posts

Joined
Sat Jan 14, 2012 1:02 am
Who is online

Users browsing this forum: No registered users and 13 guests