Skip to content

Commit

Permalink
Merge pull request #6 from carnage/keyids
Browse files Browse the repository at this point in the history
Adds the concept of multiple keys
  • Loading branch information
carnage authored Sep 29, 2017
2 parents 0096246 + 789ef1a commit c15db09
Show file tree
Hide file tree
Showing 14 changed files with 227 additions and 112 deletions.
4 changes: 3 additions & 1 deletion example/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@
// obtaining the entity manager
$entityManager = EntityManager::create($conn, $config);

\Carnage\EncryptedColumn\Configuration::register($entityManager, './enc.key');
(new \Carnage\EncryptedColumn\Setup())
->withKeyPath('./enc.key')
->register($entityManager);
45 changes: 0 additions & 45 deletions src/Configuration.php

This file was deleted.

38 changes: 38 additions & 0 deletions src/Container/KeyContainer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace Carnage\EncryptedColumn\Container;

use Carnage\EncryptedColumn\ValueObject\Key;
use Psr\Container\ContainerInterface;

final class KeyContainer implements ContainerInterface
{
/**
* @var array
*/
private $keys = [];

public function addKey(Key $key)
{
$this->keys[$key->getIdentifier()->toString()] = $key;
}

public function tagKey($tag, $id)
{
$this->keys[$tag] = $this->keys[$id];
}

public function get($id)
{
if (!$this->has($id)) {
throw NotFoundException::serviceNotFoundInContainer($id, $this->keys);
}

return $this->keys[$id];
}

public function has($id): bool
{
return isset($this->keys[$id]);
}
}
3 changes: 2 additions & 1 deletion src/Dbal/EncryptedColumnLegacySupport.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ public function convertToPHPValue($value, AbstractPlatform $platform)
'data' => $value,
'classname' => ValueHolder::class,
'serializer' => 'legacy',
'encryptor' => 'legacy'
'encryptor' => 'legacy',
'keyid' => 'legacy',
];
}

Expand Down
5 changes: 3 additions & 2 deletions src/Encryptor/EncryptorInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
namespace Carnage\EncryptedColumn\Encryptor;

use Carnage\EncryptedColumn\Container\VersionedInterface;
use Carnage\EncryptedColumn\ValueObject\Key;

interface EncryptorInterface extends VersionedInterface
{
public function encrypt($data);
public function encrypt($data, Key $key);

public function decrypt($data);
public function decrypt($data, Key $key);
}
29 changes: 7 additions & 22 deletions src/Encryptor/HaliteEncryptor.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,22 @@

use Carnage\EncryptedColumn\ValueObject\EncryptorIdentity;
use Carnage\EncryptedColumn\ValueObject\IdentityInterface;
use ParagonIE\Halite\Halite;
use Carnage\EncryptedColumn\ValueObject\Key;
use ParagonIE\Halite\KeyFactory;
use ParagonIE\Halite\Symmetric;

class HaliteEncryptor implements EncryptorInterface
{
const IDENTITY = 'halite';
/**
* @var string
*/
private $keypath;
private $key;

public function __construct($keypath)
{
$this->keypath = $keypath;
}

public function encrypt($data)
public function encrypt($data, Key $key)
{
return Symmetric\Crypto::encrypt($data, $this->loadKey());
return Symmetric\Crypto::encrypt($data, $this->loadKey($key));
}

public function decrypt($data)
public function decrypt($data, Key $key)
{
return Symmetric\Crypto::decrypt($data, $this->loadKey());
return Symmetric\Crypto::decrypt($data, $this->loadKey($key));
}

public function getIdentifier(): IdentityInterface
Expand All @@ -41,13 +31,8 @@ public function getIdentifier(): IdentityInterface
* @return Symmetric\EncryptionKey
* @throws \ParagonIE\Halite\Alerts\CannotPerformOperation
*/
private function loadKey()
private function loadKey(Key $key)
{
if ($this->key === null) {
$this->key = KeyFactory::loadEncryptionKey($this->keypath);
}

return $this->key;
return KeyFactory::loadEncryptionKey($key->getKeyInfo());
}

}
16 changes: 4 additions & 12 deletions src/Encryptor/LegacyEncryptor.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,24 @@
use Carnage\EncryptedColumn\Exception\PopArtPenguinException;
use Carnage\EncryptedColumn\ValueObject\EncryptorIdentity;
use Carnage\EncryptedColumn\ValueObject\IdentityInterface;
use Carnage\EncryptedColumn\ValueObject\Key;
use phpseclib\Crypt\Base;
use phpseclib\Crypt\Rijndael;

class LegacyEncryptor implements EncryptorInterface
{
const IDENTITY = 'legacy';
/**
* @var string
*/
private $secret;

public function __construct($secret)
{
$this->secret = $secret;
}

public function encrypt($data)
public function encrypt($data, Key $key)
{
throw new PopArtPenguinException();
}

public function decrypt($data)
public function decrypt($data, Key $key)
{
$cipher = new Rijndael(Base::MODE_ECB);
$cipher->setBlockLength(256);
$cipher->setKey($this->secret);
$cipher->setKey($key->getKeyInfo());
$cipher->padding = false;

return trim($cipher->decrypt(base64_decode($data)));
Expand Down
23 changes: 13 additions & 10 deletions src/Service/EncryptionService.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,22 +38,22 @@ class EncryptionService
private $serializers;

/**
* EncryptionService constructor.
* @param EncryptorInterface $encryptor
* @param SerializerInterface $serializer
* @param ContainerInterface $encryptors
* @param ContainerInterface $serializers
* @var ContainerInterface
*/
private $keys;

public function __construct(
EncryptorInterface $encryptor,
SerializerInterface $serializer,
ContainerInterface $encryptors,
ContainerInterface $serializers
ContainerInterface $serializers,
ContainerInterface $keys
) {
$this->encryptor = $encryptor;
$this->serializer = $serializer;
$this->encryptors = $encryptors;
$this->serializers = $serializers;
$this->keys = $keys;
}

public function decryptField(EncryptedColumnVO $value)
Expand Down Expand Up @@ -90,13 +90,15 @@ public function encryptField($value): EncryptedColumnVO
throw new \Exception('This column type only supports encrypting objects');
}

$data = $this->encryptor->encrypt($this->serializer->serialize($value));
$key = $this->keys->get('default');
$data = $this->encryptor->encrypt($this->serializer->serialize($value), $key);

return new EncryptedColumnVO(
get_class($value),
$data,
$this->encryptor->getIdentifier(),
$this->serializer->getIdentifier()
$this->serializer->getIdentifier(),
$key->getIdentifier()
);
}

Expand All @@ -108,10 +110,11 @@ private function createInitializer(EncryptedColumnVO $value): \Closure
{
$serializer = $this->serializers->get($value->getSerializerIdentifier()->toString());
$encryptor = $this->encryptors->get($value->getEncryptorIdentifier()->toString());
$key = $this->keys->get($value->getKeyIdentifier()->toString());

return function(& $wrappedObject, LazyLoadingInterface $proxy, $method, array $parameters, & $initializer) use ($serializer, $encryptor, $value) {
return function(& $wrappedObject, LazyLoadingInterface $proxy, $method, array $parameters, & $initializer) use ($serializer, $encryptor, $key, $value) {
$initializer = null;
$wrappedObject = $serializer->unserialize($encryptor->decrypt($value->getData()));
$wrappedObject = $serializer->unserialize($encryptor->decrypt($value->getData(), $key));

return true;
};
Expand Down
35 changes: 34 additions & 1 deletion src/Setup.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Carnage\EncryptedColumn;

use Carnage\EncryptedColumn\Container\KeyContainer;
use Carnage\EncryptedColumn\Container\VersionedContainer;
use Carnage\EncryptedColumn\Dbal\EncryptedColumn;
use Carnage\EncryptedColumn\Dbal\EncryptedColumnLegacySupport;
Expand All @@ -10,13 +11,21 @@
use Carnage\EncryptedColumn\Serializer\LegacySerializer;
use Carnage\EncryptedColumn\Serializer\PhpSerializer;
use Carnage\EncryptedColumn\Service\EncryptionService;
use Carnage\EncryptedColumn\ValueObject\Key;
use Carnage\EncryptedColumn\ValueObject\KeyIdentity;
use Doctrine\ORM\EntityManagerInterface;

final class Setup
{
private $keyPath;
private $enableLegacy = false;
private $legacyKey;
private $keyContainer;

public function __construct()
{
$this->keyContainer = new KeyContainer();
}

public function register(EntityManagerInterface $em)
{
Expand All @@ -31,12 +40,35 @@ public function enableLegacy(string $legacyKey)
{
$this->enableLegacy = true;
$this->legacyKey = $legacyKey;

$key = new Key($legacyKey);
$this->keyContainer->addKey($key);
$this->keyContainer->tagKey('legacy', $key->getIdentifier()->toString());

return $this;
}

public function withKeyPath(string $keypath)
{
$this->keyPath = $keypath;

$key = new Key($keypath);
$this->keyContainer->addKey($key);
$this->keyContainer->tagKey('default', $key->getIdentifier()->toString());

return $this;
}

public function withKey(string $key, array $tags = [])
{
$key = new Key($key);
$keyId = $key->getIdentifier()->toString();
$this->keyContainer->addKey($key);

foreach ($tags as $tag) {
$this->keyContainer->tagKey($tag, $keyId);
}

return $this;
}

Expand All @@ -48,7 +80,8 @@ private function buildEncryptionService(): EncryptionService
$encryptors->get(HaliteEncryptor::IDENTITY),
$serializers->get(PhpSerializer::IDENTITY),
$encryptors,
$serializers
$serializers,
$this->keyContainer
);
}

Expand Down
Loading

0 comments on commit c15db09

Please sign in to comment.