10/10/2015 - SYMFONY
In example below, we're going to create a symfony vendor bundle so that we can install it with composer to use it in our main project. This example uses encryption and decryption features.
Inanzzz-MBP:Documents inanzzz$ composer create-project symfony/framework-standard-edition encrypt-decrypt
Inanzzz-MacBook-Pro:encrypt-decrypt inanzzz$ php app/console generate:bundle --namespace=Security/CryptBundle
After removing certain files and directories from the application, you should end up with structure below.
encrypt-decrypt
src
Security
CryptBundle
DependencyInjection
Configuration.php
SecurityCryptExtension.php
SecurityCryptBundle.php
.htaccess
.gitignore
composer.json
LICENSE
README.md
Replace the current content with the one below and run composer update
.
{
"name": "inanzzz/encrypt-decrypt",
"license": "MIT",
"type": "library",
"description": "Used for encryption and decryption processes.",
"autoload": {
"psr-0": {
"Security\\CryptBundle": "src/"
}
},
"require": {
"php": ">=5.3.3",
"symfony/symfony": "2.6.*"
},
"minimum-stability": "stable"
}
/vendor/
/composer.phar
/composer.lock
# encrypt-decrypt/src/Security/CryptBundle/Service/CryptorServiceInterface.php
namespace Security\CryptBundle\Service;
interface CryptorServiceInterface
{
public function encrypt($value);
public function decrypt($value);
}
# encrypt-decrypt/src/Security/CryptBundle/Service/CryptorService.php
namespace Security\CryptBundle\Service;
use Security\CryptBundle\Exception\InvalidValueException;
class CryptorService implements CryptorServiceInterface
{
private $hash;
private $algorithm;
private $mode;
private $cipher;
public function __construct(
$secret = 'hgvER5445ds5sd@£$%',
$algorithm = 'rijndael-128',
$mode = 'ecb'
) {
$this->hash = sha1($secret);
$this->algorithm = $algorithm;
$this->mode = $mode;
}
public function encrypt($plainString)
{
$this->initiate($plainString);
$encryptedValue = mcrypt_generic($this->cipher, $plainString);
$this->finalise();
return base64_encode($encryptedValue);
}
public function decrypt($encryptedValue)
{
$decodedValue = base64_decode($encryptedValue, true);
if ($decodedValue === false) {
throw new InvalidValueException(sprintf('Given value [%s] is not a valid base64 string.', $encryptedValue));
}
$this->initiate($decodedValue);
$decryptedValue = mdecrypt_generic($this->cipher, $decodedValue);
$this->finalise();
return $decryptedValue;
}
private function initiate($value)
{
if (!is_string($value)) {
throw new InvalidValueException(sprintf('Given value [%s] is not a string.', $value));
}
if (mb_strlen($value) == 0) {
throw new InvalidValueException(sprintf('Given value [%s] is empty.', $value));
}
// Open the cipher
$this->cipher = mcrypt_module_open($this->algorithm, '', $this->mode, '');
// Get key size
$keySize = mcrypt_enc_get_key_size($this->cipher);
// Get key
$key = substr($this->hash, 0, $keySize);
// Get iv size
$ivSize = mcrypt_enc_get_iv_size($this->cipher);
// Get iv
$iv = mcrypt_create_iv($ivSize, MCRYPT_DEV_RANDOM);
// Initialise encryption
mcrypt_generic_init($this->cipher, $key, $iv);
}
private function finalise()
{
// Terminate encryption handler
mcrypt_generic_deinit($this->cipher);
// Close module
mcrypt_module_close($this->cipher);
}
}
# encrypt-decrypt/src/Security/CryptBundle/Exception/InvalidValueException.php
namespace Security\CryptBundle\Exception;
use RuntimeException;
class InvalidValueException extends RuntimeException
{
}
services:
security_crypt.service.cryptor:
class: Security\CryptBundle\Service\CryptorService
arguments:
- %security_crypt.secret%
- %security_crypt.algorithm%
- %security_crypt.mode%
# encrypt-decrypt/src/Security/CryptBundle/DependencyInjection/Configuration.php
namespace Security\CryptBundle\DependencyInjection;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
class Configuration implements ConfigurationInterface
{
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('security_crypt');
$rootNode
->children()
->scalarNode('secret')->isRequired()->cannotBeEmpty()->end()
->scalarNode('algorithm')->isRequired()->cannotBeEmpty()->end()
->scalarNode('mode')->isRequired()->cannotBeEmpty()->end()
->end();
return $treeBuilder;
}
}
# encrypt-decrypt/src/Security/CryptBundle/DependencyInjection/SecurityCryptExtension.php
namespace Security\CryptBundle\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;
class SecurityCryptExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$container->setParameter('security_crypt.secret', $config['secret']);
$container->setParameter('security_crypt.algorithm', $config['algorithm']);
$container->setParameter('security_crypt.mode', $config['mode']);
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
}
}
We should now have structure below.
encrypt-decrypt
src
Security
CryptBundle
DependencyInjection
Configuration.php
SecurityCryptExtension.php
Exception
InvalidValueException.php
Resources
config
service.yml
Service
CryptorServiceInterface.php
CryptorService.php
SecurityCryptBundle.php
.htaccess
.gitignore
composer.json
LICENSE
README.md
First of all, create a remote Git repo named as encrypt-decrypt
then follow the steps below to initiate it so that you can start developing it.
Inanzzz-MBP:encrypt-decrypt inanzzz$ git init
Inanzzz-MBP:encrypt-decrypt inanzzz$ git add --all
Inanzzz-MBP:encrypt-decrypt inanzzz$ git commit -m 'First commit'
Inanzzz-MBP:encrypt-decrypt inanzzz$ git remote add origin https://github.com/Inanzzz/encrypt-decrypt.git
Inanzzz-MBP:encrypt-decrypt inanzzz$ git push -u origin master
Add parts below to current content and run composer update inanzzz/encrypt-decrypt
.
{
...
"repositories": [
{
"type": "git",
"url": "git@github.com:Inanzzz/encrypt-decrypt.git"
},
...
],
"require": {
...
"inanzzz/encrypt-decrypt": "dev-master"
...
},
"minimum-stability": "stable"
...
}
If you want you can change repositories
block with the one below.
{
"repositories": [
{
"type": "vcs",
"url": "https://github.com/Inanzzz/encrypt-decrypt.git"
}
}
If you want to get rid of repositories
block then you need to submit your new package/bundle to Packagist. Everytime you update your bundle, you must login and update the Packagist by "Force Update" button or setup an "auto update" task.
After registering the bundle, you can access its service with security_crypt.service.cryptor
service name.
new Security\CryptBundle\SecurityCryptBundle()
security_crypt:
secret: my_secret_value
algorithm: rijndael-128
mode: ecb
Now you can inject security_crypt.service.cryptor
service to anywhere you want in your application. Encrypted value is over decrypted value.
prJZvmy/gkLwAFjTBuI9Wg==
Hello
XrMKs6vAxB20JuYc0+vXOw==
Bye