From 79d8dde7c28f01eb580faa846af806fcad511b1e Mon Sep 17 00:00:00 2001 From: Nicolas MURE Date: Fri, 13 May 2016 16:17:13 +0200 Subject: [PATCH] cypher method choice --- CHANGELOG.md | 12 ++++++ DependencyInjection/Configuration.php | 10 +++++ .../NmureEncryptorExtension.php | 38 ++++++++++++------- Encryptor/Encryptor.php | 18 +++++++-- README.md | 8 +++- Tests/Adapter/Base64AdapterTest.php | 2 +- .../NmureEncryptorExtensionTest.php | 19 ++++++++++ .../EncryptorInterfaceTestHelper.php | 2 + Tests/Encryptor/EncryptorTest.php | 2 +- composer.json | 2 +- 10 files changed, 91 insertions(+), 22 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..a13d89b --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,12 @@ +# Changelog + +## v0.3.0 (2016-05-13) +Ability to choose the cipher method for each encryptors. +BC break with previous version due to the Encryptor's __constructor parameters changes. + +## v0.2.0 (2016-04-07) +Ability to declare multiple encryptors. +BC break with previous version due to configuration declaration changes. + +## v0.1.0 (2016-04-04) +Initial commit. diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index a8070f9..290dbc3 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -28,10 +28,20 @@ public function getConfigTreeBuilder() ->prototype('array') ->children() ->scalarNode('secret') + ->info('The encryption key') ->isRequired() ->cannotBeEmpty() ->end() + ->scalarNode('cipher') + ->info('The cipher method') + ->defaultValue('AES-256-CBC') + ->end() + ->integerNode('iv_length') + ->info('The length of the Initialization Vector, in number of bytes.') + ->defaultValue(16) + ->end() ->booleanNode('prefer_base64') + ->info('Indicates if the encrypted data should be converted to base64') ->defaultTrue() ->end() ->end() diff --git a/DependencyInjection/NmureEncryptorExtension.php b/DependencyInjection/NmureEncryptorExtension.php index 6bcab80..e741c6a 100644 --- a/DependencyInjection/NmureEncryptorExtension.php +++ b/DependencyInjection/NmureEncryptorExtension.php @@ -6,6 +6,7 @@ use Symfony\Component\Config\FileLocator; use Symfony\Component\HttpKernel\DependencyInjection\Extension; use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; /** * This is the class that loads and manages your bundle configuration. @@ -14,13 +15,6 @@ */ class NmureEncryptorExtension extends Extension { - /** - * Indicates if the compilation of the container is required. - * - * @var boolean - */ - private $isCompilationRequired; - /** * {@inheritdoc} */ @@ -32,11 +26,6 @@ public function load(array $configs, ContainerBuilder $container) foreach ($config['encryptors'] as $name => $settings) { $this->configureEncryptor($name, $settings, $container); } - - // resolving decorated services if needed - if ($this->isCompilationRequired) { - $container->compile(); - } } /** @@ -46,9 +35,13 @@ public function load(array $configs, ContainerBuilder $container) */ private function configureEncryptor($name, array $settings, ContainerBuilder $container) { + $this->assertSupportedCipher($settings['cipher']); + $serviceName = sprintf('nmure_encryptor.%s', $name); $container->register($serviceName, 'Nmure\EncryptorBundle\Encryptor\Encryptor') - ->addArgument($settings['secret']); + ->addArgument($settings['secret']) + ->addArgument($settings['cipher']) + ->addArgument($settings['iv_length']); if ($settings['prefer_base64']) { $decoratorServiceName = sprintf('nmure_encryptor.adapter.base64.%s', $name); @@ -56,8 +49,25 @@ private function configureEncryptor($name, array $settings, ContainerBuilder $co ->addArgument(new Reference(sprintf('%s.inner', $decoratorServiceName))) ->setPublic(false) ->setDecoratedService($serviceName); + } + } - $this->isCompilationRequired = true; + /** + * Asserts the given cipher is supported. + * + * @param string $cipher + * + * @throws InvalidConfigurationException When the given cipher is not supported. + */ + private function assertSupportedCipher($cipher) + { + $supportedCiphers = openssl_get_cipher_methods(); + if (!in_array($cipher, $supportedCiphers)) { + throw new InvalidConfigurationException(sprintf( + '%s cipher method is not supported. The supported cipher methods by your php installation are %s .', + $cipher, + implode(', ', $supportedCiphers) + )); } } } diff --git a/Encryptor/Encryptor.php b/Encryptor/Encryptor.php index eaf273e..97b9e87 100644 --- a/Encryptor/Encryptor.php +++ b/Encryptor/Encryptor.php @@ -5,10 +5,17 @@ class Encryptor implements EncryptorInterface { /** + * The encryption key. * @var string */ private $secret; + /** + * The cipher method. + * @var string + */ + private $cipher; + /** * Initialization Vector. * @var string @@ -19,11 +26,14 @@ class Encryptor implements EncryptorInterface * Constructor. * * @param string $secret The encryption key. + * @param string $cipher The cipher method + * @param int $ivLength The length of Initialization Vector, in number of bytes. */ - public function __construct($secret) + public function __construct($secret, $cipher, $ivLength) { $this->secret = $secret; - $this->iv = openssl_random_pseudo_bytes(16); + $this->cipher = $cipher; + $this->iv = openssl_random_pseudo_bytes($ivLength); } /** @@ -31,7 +41,7 @@ public function __construct($secret) */ public function encrypt($data) { - return openssl_encrypt($data, 'AES-256-CBC', $this->secret, OPENSSL_RAW_DATA, $this->iv); + return openssl_encrypt($data, $this->cipher, $this->secret, OPENSSL_RAW_DATA, $this->iv); } /** @@ -39,7 +49,7 @@ public function encrypt($data) */ public function decrypt($encrypted) { - return openssl_decrypt($encrypted, 'AES-256-CBC', $this->secret, OPENSSL_RAW_DATA, $this->iv); + return openssl_decrypt($encrypted, $this->cipher, $this->secret, OPENSSL_RAW_DATA, $this->iv); } /** diff --git a/README.md b/README.md index 6d4e141..4767ce4 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Open a command console, enter your project directory and execute the following command to download the latest stable version of this bundle: ```bash -$ composer require nmure/encryptor-bundle "~0.2.0" +$ composer require nmure/encryptor-bundle "~0.3.0" ``` This command requires you to have Composer installed globally, as explained @@ -48,6 +48,9 @@ nmure_encryptor: encryptors: my_encryptor: secret: theSecretKeyGoesHere # should be a complex key defined in your parameters.yml file + cipher: AES-256-CBC # optional, default to AES-256-CBC + # the length of the Initialization Vector, in number of bytes + iv_length: 16 # optional, default 16 (according to the default cipher) # you can add as many encryptors as you want my_other_encryptor: secret: myOtherSecretKey # you should use one unique secret key by encryptor @@ -99,3 +102,6 @@ More informations in the [LICENSE](/LICENSE) file. ## Issues / feature requests Please use this Github repository page to report issues and to ask / propose feature. + +## Changes +See the [changelog](/CHANGELOG.md "changelog") for more infos. diff --git a/Tests/Adapter/Base64AdapterTest.php b/Tests/Adapter/Base64AdapterTest.php index 850845c..c5b9dde 100644 --- a/Tests/Adapter/Base64AdapterTest.php +++ b/Tests/Adapter/Base64AdapterTest.php @@ -42,7 +42,7 @@ public function testGetSetIv() */ protected function getConcreteEncryptor() { - $this->encryptor = new Encryptor($this->secret); + $this->encryptor = new Encryptor($this->secret, $this->cipher, $this->ivLength); return new Base64Adapter($this->encryptor); } } diff --git a/Tests/DependencyInjection/NmureEncryptorExtensionTest.php b/Tests/DependencyInjection/NmureEncryptorExtensionTest.php index 155367e..184c421 100644 --- a/Tests/DependencyInjection/NmureEncryptorExtensionTest.php +++ b/Tests/DependencyInjection/NmureEncryptorExtensionTest.php @@ -61,6 +61,24 @@ public function testSecretMustBeDefined() $loader->load(array($config), new ContainerBuilder()); } + /** + * @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + * @expectedExceptionMessage cipher method is not supported + */ + public function testUnsupportedCipherMethod() + { + $loader = new NmureEncryptorExtension(); + $config = array( + 'encryptors' => array( + 'first_encryptor' => array( + 'secret' => 'iAmTheFirstSecretKey', + 'cipher' => 'unsupportedCipher', + ), + ), + ); + $loader->load(array($config), new ContainerBuilder()); + } + public function testValidConfiguration() { $configuration = new ContainerBuilder(); @@ -73,6 +91,7 @@ public function testValidConfiguration() ), ); $loader->load(array($config), $configuration); + $configuration->compile(); $this->assertInstanceOf('Nmure\EncryptorBundle\Encryptor\EncryptorInterface', $configuration->get('nmure_encryptor.first_encryptor')); // default setting diff --git a/Tests/Encryptor/EncryptorInterfaceTestHelper.php b/Tests/Encryptor/EncryptorInterfaceTestHelper.php index 0a83977..c862f26 100644 --- a/Tests/Encryptor/EncryptorInterfaceTestHelper.php +++ b/Tests/Encryptor/EncryptorInterfaceTestHelper.php @@ -7,6 +7,8 @@ abstract class EncryptorInterfaceTestHelper extends TestCase { protected $secret = 'thisIsMySecretTestingKey'; + protected $cipher = 'AES-256-CBC'; + protected $ivLength = 16; protected $data = 'Lorem ipsum dolor'; public function testDefaultEncryptDecrypt() diff --git a/Tests/Encryptor/EncryptorTest.php b/Tests/Encryptor/EncryptorTest.php index 7ba8e24..1cd8253 100644 --- a/Tests/Encryptor/EncryptorTest.php +++ b/Tests/Encryptor/EncryptorTest.php @@ -11,6 +11,6 @@ class EncryptorTest extends EncryptorInterfaceTestHelper */ protected function getConcreteEncryptor() { - return new Encryptor($this->secret); + return new Encryptor($this->secret, $this->cipher, $this->ivLength); } } diff --git a/composer.json b/composer.json index 8226d89..86e84d6 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "nmure/encryptor-bundle", "type": "symfony-bundle", - "description": "Symfony data encryptor bundle using open_ssl", + "description": "A data encryptor Bundle for Symfony using PHP's openssl", "keywords": ["encryption", "encrypt", "decrypt", "data", "open", "ssl", "security", "hash"], "license": "MIT", "authors": [