123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- declare(strict_types=1);
- namespace Magento\Framework\Encryption\Test\Unit;
- use Magento\Framework\Encryption\Adapter\SodiumChachaIetf;
- use Magento\Framework\Encryption\Encryptor;
- use Magento\Framework\Encryption\Crypt;
- use Magento\Framework\Encryption\KeyValidator;
- use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
- class EncryptorTest extends \PHPUnit\Framework\TestCase
- {
- const CRYPT_KEY_1 = 'g9mY9KLrcuAVJfsmVUSRkKFLDdUPVkaZ';
- const CRYPT_KEY_2 = '7wEjmrliuqZQ1NQsndSa8C8WHvddeEbN';
- /**
- * @var \Magento\Framework\Encryption\Encryptor
- */
- private $encryptor;
- /**
- * @var \PHPUnit_Framework_MockObject_MockObject
- */
- private $randomGeneratorMock;
- /**
- * @var KeyValidator|\PHPUnit_Framework_MockObject_MockObject
- */
- private $keyValidatorMock;
- protected function setUp()
- {
- $this->randomGeneratorMock = $this->createMock(\Magento\Framework\Math\Random::class);
- $deploymentConfigMock = $this->createMock(\Magento\Framework\App\DeploymentConfig::class);
- $deploymentConfigMock->expects($this->any())
- ->method('get')
- ->with(Encryptor::PARAM_CRYPT_KEY)
- ->will($this->returnValue(self::CRYPT_KEY_1));
- $this->keyValidatorMock = $this->createMock(KeyValidator::class);
- $this->encryptor = (new ObjectManager($this))->getObject(
- \Magento\Framework\Encryption\Encryptor::class,
- [
- 'random' => $this->randomGeneratorMock,
- 'deploymentConfig' => $deploymentConfigMock,
- 'keyValidator' => $this->keyValidatorMock
- ]
- );
- }
- public function testGetHashNoSalt()
- {
- $this->randomGeneratorMock->expects($this->never())->method('getRandomString');
- $expected = '5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8';
- $actual = $this->encryptor->getHash('password');
- $this->assertEquals($expected, $actual);
- }
- public function testGetHashSpecifiedSalt()
- {
- $this->randomGeneratorMock->expects($this->never())->method('getRandomString');
- $expected = '13601bda4ea78e55a07b98866d2be6be0744e3866f13c00c811cab608a28f322:salt:1';
- $actual = $this->encryptor->getHash('password', 'salt');
- $this->assertEquals($expected, $actual);
- }
- public function testGetHashRandomSaltDefaultLength()
- {
- $salt = '-----------random_salt----------';
- $this->randomGeneratorMock
- ->expects($this->once())
- ->method('getRandomString')
- ->with(32)
- ->will($this->returnValue($salt));
- $expected = 'a1c7fc88037b70c9be84d3ad12522c7888f647915db78f42eb572008422ba2fa:' . $salt . ':1';
- $actual = $this->encryptor->getHash('password', true);
- $this->assertEquals($expected, $actual);
- }
- public function testGetHashRandomSaltSpecifiedLength()
- {
- $this->randomGeneratorMock
- ->expects($this->once())
- ->method('getRandomString')
- ->with(11)
- ->will($this->returnValue('random_salt'));
- $expected = '4c5cab8dd00137d11258f8f87b93fd17bd94c5026fc52d3c5af911dd177a2611:random_salt:1';
- $actual = $this->encryptor->getHash('password', 11);
- $this->assertEquals($expected, $actual);
- }
- /**
- * @param string $password
- * @param string $hash
- * @param bool $expected
- *
- * @dataProvider validateHashDataProvider
- */
- public function testValidateHash($password, $hash, $expected)
- {
- $actual = $this->encryptor->validateHash($password, $hash);
- $this->assertEquals($expected, $actual);
- }
- /**
- * @return array
- */
- public function validateHashDataProvider()
- {
- return [
- ['password', 'hash:salt:1', false],
- ['password', '67a1e09bb1f83f5007dc119c14d663aa:salt:0', true],
- ['password', '13601bda4ea78e55a07b98866d2be6be0744e3866f13c00c811cab608a28f322:salt:1', true],
- ];
- }
- /**
- * @param mixed $key
- *
- * @dataProvider encryptWithEmptyKeyDataProvider
- * @expectedException \SodiumException
- */
- public function testEncryptWithEmptyKey($key)
- {
- $deploymentConfigMock = $this->createMock(\Magento\Framework\App\DeploymentConfig::class);
- $deploymentConfigMock->expects($this->any())
- ->method('get')
- ->with(Encryptor::PARAM_CRYPT_KEY)
- ->will($this->returnValue($key));
- $model = new Encryptor($this->randomGeneratorMock, $deploymentConfigMock);
- $value = 'arbitrary_string';
- $this->assertEquals($value, $model->encrypt($value));
- }
- /**
- * @return array
- */
- public function encryptWithEmptyKeyDataProvider()
- {
- return [[null], [0], [''], ['0']];
- }
- /**
- * @param mixed $key
- *
- * @dataProvider decryptWithEmptyKeyDataProvider
- */
- public function testDecryptWithEmptyKey($key)
- {
- $deploymentConfigMock = $this->createMock(\Magento\Framework\App\DeploymentConfig::class);
- $deploymentConfigMock->expects($this->any())
- ->method('get')
- ->with(Encryptor::PARAM_CRYPT_KEY)
- ->will($this->returnValue($key));
- $model = new Encryptor($this->randomGeneratorMock, $deploymentConfigMock);
- $value = 'arbitrary_string';
- $this->assertEquals('', $model->decrypt($value));
- }
- /**
- * @return array
- */
- public function decryptWithEmptyKeyDataProvider()
- {
- return [[null], [0], [''], ['0']];
- }
- public function testEncrypt()
- {
- // sample data to encrypt
- $data = 'Mares eat oats and does eat oats, but little lambs eat ivy.';
- $actual = $this->encryptor->encrypt($data);
- // Extract the initialization vector and encrypted data
- $parts = explode(':', $actual, 3);
- list(, , $encryptedData) = $parts;
- $crypt = new SodiumChachaIetf(self::CRYPT_KEY_1);
- // Verify decrypted matches original data
- $this->assertEquals($data, $crypt->decrypt(base64_decode((string)$encryptedData)));
- }
- public function testDecrypt()
- {
- $message = 'Mares eat oats and does eat oats, but little lambs eat ivy.';
- $encrypted = $this->encryptor->encrypt($message);
- $this->assertEquals($message, $this->encryptor->decrypt($encrypted));
- }
- public function testLegacyDecrypt()
- {
- // sample data to encrypt
- $data = '0:2:z3a4ACpkU35W6pV692U4ueCVQP0m0v0p:' .
- 'DhEG8/uKGGq92ZusqrGb6X/9+2Ng0QZ9z2UZwljgJbs5/A3LaSnqcK0oI32yjHY49QJi+Z7q1EKu2yVqB8EMpA==';
- $actual = $this->encryptor->decrypt($data);
- // Extract the initialization vector and encrypted data
- $parts = explode(':', $data, 4);
- list(, , $iv, $encrypted) = $parts;
- // Decrypt returned data with RIJNDAEL_256 cipher, cbc mode
- $crypt = new Crypt(self::CRYPT_KEY_1, MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC, $iv);
- // Verify decrypted matches original data
- $this->assertEquals($encrypted, base64_encode($crypt->encrypt($actual)));
- }
- public function testEncryptDecryptNewKeyAdded()
- {
- $deploymentConfigMock = $this->createMock(\Magento\Framework\App\DeploymentConfig::class);
- $deploymentConfigMock->expects($this->at(0))
- ->method('get')
- ->with(Encryptor::PARAM_CRYPT_KEY)
- ->will($this->returnValue(self::CRYPT_KEY_1));
- $deploymentConfigMock->expects($this->at(1))
- ->method('get')
- ->with(Encryptor::PARAM_CRYPT_KEY)
- ->will($this->returnValue(self::CRYPT_KEY_1 . "\n" . self::CRYPT_KEY_2));
- $model1 = new Encryptor($this->randomGeneratorMock, $deploymentConfigMock);
- // simulate an encryption key is being added
- $model2 = new Encryptor($this->randomGeneratorMock, $deploymentConfigMock);
- // sample data to encrypt
- $data = 'Mares eat oats and does eat oats, but little lambs eat ivy.';
- // encrypt with old key
- $encryptedData = $model1->encrypt($data);
- $decryptedData = $model2->decrypt($encryptedData);
- $this->assertSame($data, $decryptedData, 'Encryptor failed to decrypt data encrypted by old keys.');
- }
- public function testValidateKey()
- {
- $this->keyValidatorMock->method('isValid')->willReturn(true);
- $this->encryptor->validateKey(self::CRYPT_KEY_1);
- }
- /**
- * @expectedException \Exception
- */
- public function testValidateKeyInvalid()
- {
- $this->keyValidatorMock->method('isValid')->willReturn(false);
- $this->encryptor->validateKey('----- ');
- }
- /**
- * @return array
- */
- public function useSpecifiedHashingAlgoDataProvider()
- {
- return [
- ['password', 'salt', Encryptor::HASH_VERSION_MD5,
- '67a1e09bb1f83f5007dc119c14d663aa:salt:0'],
- ['password', 'salt', Encryptor::HASH_VERSION_SHA256,
- '13601bda4ea78e55a07b98866d2be6be0744e3866f13c00c811cab608a28f322:salt:1'],
- ['password', false, Encryptor::HASH_VERSION_MD5,
- '5f4dcc3b5aa765d61d8327deb882cf99'],
- ['password', false, Encryptor::HASH_VERSION_SHA256,
- '5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8']
- ];
- }
- /**
- * @dataProvider useSpecifiedHashingAlgoDataProvider
- *
- * @param $password
- * @param $salt
- * @param $hashAlgo
- * @param $expected
- */
- public function testGetHashMustUseSpecifiedHashingAlgo($password, $salt, $hashAlgo, $expected)
- {
- $hash = $this->encryptor->getHash($password, $salt, $hashAlgo);
- $this->assertEquals($expected, $hash);
- }
- }
|