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:

Code: Select all

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?
Last edited by straightlight on Fri Apr 17, 2020 6:45 pm, edited 1 time in total.
Reason: Added code tags.

New member

Posts

Joined
Fri Aug 28, 2015 10:26 pm

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


Dedication and passion goes to those who are able to push and merge a project.

Regards,
Straightlight
Programmer / Opencart Tester


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

Edited, since it is no longer compatible with PHP v7.3+ as also explained here: viewtopic.php?f=179&t=202581#p753726.
Last edited by straightlight on Wed May 01, 2019 12:30 am, edited 6 times in total.

Dedication and passion goes to those who are able to push and merge a project.

Regards,
Straightlight
Programmer / Opencart Tester


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.

Dedication and passion goes to those who are able to push and merge a project.

Regards,
Straightlight
Programmer / Opencart Tester


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.

Dedication and passion goes to those who are able to push and merge a project.

Regards,
Straightlight
Programmer / Opencart Tester


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.

Dedication and passion goes to those who are able to push and merge a project.

Regards,
Straightlight
Programmer / Opencart Tester


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.

www.add-creative.co.uk


Expert Member

Posts

Joined
Sat Jan 14, 2012 1:02 am
Location - United Kingdom

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.

Dedication and passion goes to those who are able to push and merge a project.

Regards,
Straightlight
Programmer / Opencart Tester


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?

www.add-creative.co.uk


Expert Member

Posts

Joined
Sat Jan 14, 2012 1:02 am
Location - United Kingdom

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.

Dedication and passion goes to those who are able to push and merge a project.

Regards,
Straightlight
Programmer / Opencart Tester


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.

www.add-creative.co.uk


Expert Member

Posts

Joined
Sat Jan 14, 2012 1:02 am
Location - United Kingdom

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) {
		$iv = random_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) {
		$encrypted = base64_decode(strtr($value, '-_,', '+/='));

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

		if (strlen($encrypted) <= $iv_len + $tag_len) {
			return '';
		}

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

		return trim(openssl_decrypt(substr($encrypted, $iv_len + $tag_len), 'aes-256-gcm', hash('sha256', $key, true), OPENSSL_RAW_DATA, $iv, $tag));
	}
}
Edit: Remove ?> to keep same style as 3.x and removed unneeded key assignment in openssl 'aes-256-gcm' version.
Edit: Added length check and use random_bytes in openssl 'aes-256-gcm' version.
Last edited by ADD Creative on Tue Sep 08, 2020 12:12 am, edited 4 times in total.

www.add-creative.co.uk


Expert Member

Posts

Joined
Sat Jan 14, 2012 1:02 am
Location - United Kingdom

Post by straightlight » Mon Oct 22, 2018 3:18 am

Interesting with this sodium hashing method …

According to this site: https://lukasmestan.com/install-libsodi ... n-in-php7/ , the sodium hash can also be used prior to PHP v7.2 . However, it won't support password hashing below PHP v7.2 release … this should be addressed on GitHub to indicate that password hashing should be implicit within the encryption methods for security purposes and in order to do that, PHP v7.2 should be the minimum requirements nowadays … :ponder:

Dedication and passion goes to those who are able to push and merge a project.

Regards,
Straightlight
Programmer / Opencart Tester


Legendary Member

Posts

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

Post by straightlight » Mon Oct 22, 2018 3:22 am

Addressed.

Dedication and passion goes to those who are able to push and merge a project.

Regards,
Straightlight
Programmer / Opencart Tester


Legendary Member

Posts

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

Post by darkhorse » Fri Nov 16, 2018 7:57 pm

When you say addressed Straightlight, could you elaborate a little. I too am having this error, OC 3.0.2.0 , Journal 2 and one step checkout with paypal pro iframe. Is there a patch on github that is tested? there seems to be some conflict with your posted solution and another posters cunning sodium suggestion and analysis of the posted code.

Uk based Opencart Developer. Love building and ranking with Opencart. Opencart > All the others!


Newbie

Posts

Joined
Tue Oct 16, 2018 5:26 am

Post by straightlight » Tue Sep 08, 2020 8:50 am

The encryption library has recently been updated on the master branch. Should be fixed now.

Dedication and passion goes to those who are able to push and merge a project.

Regards,
Straightlight
Programmer / Opencart Tester


Legendary Member

Posts

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

Users browsing this forum: No registered users and 41 guests