Skip to content
This repository has been archived by the owner on Jan 29, 2019. It is now read-only.

Commit

Permalink
Merge pull request #6 from salesupply/feature/allow-options-for-prope…
Browse files Browse the repository at this point in the history
…rty-encryption

Feature/allow options for property encryption
  • Loading branch information
rkeet-salesupply authored Mar 23, 2018
2 parents 9e379c7 + 0179c75 commit 70993f2
Show file tree
Hide file tree
Showing 10 changed files with 682 additions and 9 deletions.
28 changes: 26 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ This might also be applicable ot other local installations.

# Configuration

## Zend Framework

Make sure to add the module to you application configuration. In your `modules.config.php` make sure to include
`ZfDoctrineEncryptModule`.

## Module

`*.dist` files are provided. Copy these (remove extension) to your application and fill in the required key/salt values.
If these are filled in, it works out of the box using [Halite](https://github.com/paragonie/halite) for encryption.

Expand All @@ -33,7 +40,8 @@ as such, you must disable your `E_NOTICE` warnings in your PHP config :(
# Usage example

Simple, consider that you have an `Address` Entity, which under upcoming [EU GDPR regulation](https://www.eugdpr.org/)
requires parts of the address, such as the street, to be encrypted.
requires parts of the address, such as the street, to be encrypted. This uses the key & salt required for the config
by default

To encrypt a street name, add `@Encrypted` like so:

Expand All @@ -44,4 +52,20 @@ To encrypt a street name, add `@Encrypted` like so:
*/
protected $street;


If you need make sure that encryption is done in a unique way, such as for passwords or keys, which need decryption
(e.g. in the case that you need to create a connection string for an external API), you can provide some options.
Options provided are `spices`, `salt` and `pepper`. These must point to a property of the Entity you're encrypting, from
which then either the Salt or the Pepper or both of them are gotten and used.

/**
* @var string
* @ORM\Column(name="street", type="string", length=255, nullable=true)
* @Encrypted(spices="encryption")
*/
protected $street;

The above example expects a property `relation` to be present. The value is given for the option `spices`, as such,
the returned Entity when using `getEncryption` must implement the `SpicyInterface`.

**NOTE**: The option `spices` *may not be used* in conjunction with either `salt` or `pepper`. If you're *not* using
`spices`, you may use both `salt` and `pepper`.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"require": {
"php": "^7.2",
"51systems/doctrine-encrypt":"^6",
"doctrine/doctrine-orm-module":"^1.1"
"doctrine/doctrine-orm-module":"^1.1",
"paragonie/halite": "^4.4"
},
"autoload": {
"psr-4": {
Expand Down
8 changes: 4 additions & 4 deletions src/Adapter/HaliteAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
namespace ZfDoctrineEncryptModule\Adapter;

use DoctrineEncrypt\Encryptors\EncryptorInterface;
use ParagonIE\ConstantTime\Binary;
use ParagonIE\Halite\Alerts\InvalidKey;
use ParagonIE\Halite\HiddenString;
use ParagonIE\Halite\Symmetric\Crypto;
use ParagonIE\Halite\Symmetric\EncryptionKey;
use ParagonIE\Halite\Util as CryptoUtil;

class HaliteAdapter implements EncryptorInterface
{
Expand All @@ -26,18 +26,18 @@ class HaliteAdapter implements EncryptorInterface
* @param $key
* @param $salt
* @throws InvalidKey
* @throws \ParagonIE\Halite\Alerts\CannotPerformOperation
* @throws \TypeError
*/
public function __construct($key, $salt)
{
if (CryptoUtil::safeStrlen($key) !== \Sodium\CRYPTO_STREAM_KEYBYTES) {
if (Binary::safeStrlen($key) !== \Sodium\CRYPTO_STREAM_KEYBYTES) {

throw new InvalidKey(
'Encryption key used for ' . __CLASS__ . ' must be exactly ' . \Sodium\CRYPTO_STREAM_KEYBYTES . ' characters long'
);
}

if (CryptoUtil::safeStrlen($salt) !== \Sodium\CRYPTO_STREAM_KEYBYTES) {
if (Binary::safeStrlen($salt) !== \Sodium\CRYPTO_STREAM_KEYBYTES) {

throw new InvalidKey(
'Salt used for ' . __CLASS__ . ' must be exactly ' . \Sodium\CRYPTO_STREAM_KEYBYTES . ' characters long'
Expand Down
87 changes: 87 additions & 0 deletions src/Annotation/Encrypted.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?php

namespace ZfDoctrineEncryptModule\Annotation;

use Doctrine\Common\Annotations\Annotation\Target;

/**
* Class Encrypted
* @package ZfDoctrineEncryptModule\Annotation
*
* The below register the class as to be used as Doctrine's Annotation and only on class properties.
*
* @Annotation
* @Target("PROPERTY")
*/
class Encrypted
{
/**
* @var string linked property which implements \ZfDoctrineEncryptModule\Interfaces\SpicyInterface
*/
public $spices;

/**
* @var string linked property which implements \ZfDoctrineEncryptModule\Interfaces\SaltInterface
*/
public $salt;

/**
* @var string linked property which implements \ZfDoctrineEncryptModule\Interfaces\PepperInterface
*/
public $pepper;

/**
* @return string
*/
public function getSpices(): ?string
{
return $this->spices;
}

/**
* @param string $spices
* @return Encrypted
*/
public function setSpices(?string $spices): Encrypted
{
$this->spices = $spices;
return $this;
}

/**
* @return null|string
*/
public function getSalt(): ?string
{
return $this->salt;
}

/**
* @param null|string $salt
* @return Encrypted
*/
public function setSalt(?string $salt): Encrypted
{
$this->salt = $salt;
return $this;
}

/**
* @return null|string
*/
public function getPepper(): ?string
{
return $this->pepper;
}

/**
* @param null|string $pepper
* @return Encrypted
*/
public function setPepper(?string $pepper): Encrypted
{
$this->pepper = $pepper;
return $this;
}

}
2 changes: 1 addition & 1 deletion src/Factory/HaliteAdapterFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ class HaliteAdapterFactory implements FactoryInterface
* @param array|null $options
* @return object|HaliteAdapter
* @throws OptionsNotFoundException
* @throws \ParagonIE\Halite\Alerts\CannotPerformOperation
* @throws \ParagonIE\Halite\Alerts\InvalidKey
* @throws \TypeError
*/
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
Expand Down
2 changes: 1 addition & 1 deletion src/Factory/ZfDoctrineEncryptedServiceFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\Common\Annotations\Reader;
use DoctrineEncrypt\Encryptors\EncryptorInterface;
use DoctrineEncrypt\Subscribers\DoctrineEncryptSubscriber;
use DoctrineModule\Service\AbstractFactory;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use ZfDoctrineEncryptModule\Adapter\HaliteAdapter;
use ZfDoctrineEncryptModule\Options\ModuleOptions;
use ZfDoctrineEncryptModule\Subscriber\DoctrineEncryptSubscriber;

class ZfDoctrineEncryptedServiceFactory extends AbstractFactory
{
Expand Down
17 changes: 17 additions & 0 deletions src/Interfaces/PepperInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace ZfDoctrineEncryptModule\Interfaces;

interface PepperInterface
{
/**
* @return string
*/
public function getPepper(): string;

/**
* @param string $pepper
* @return PepperInterface
*/
public function setPepper(string $pepper): PepperInterface;
}
17 changes: 17 additions & 0 deletions src/Interfaces/SaltInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace ZfDoctrineEncryptModule\Interfaces;

interface SaltInterface
{
/**
* @return string
*/
public function getSalt(): string;

/**
* @param string $salt
* @return SaltInterface
*/
public function setSalt(string $salt): SaltInterface;
}
7 changes: 7 additions & 0 deletions src/Interfaces/SpicyInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace ZfDoctrineEncryptModule\Interfaces;

interface SpicyInterface extends SaltInterface, PepperInterface
{
}
Loading

0 comments on commit 70993f2

Please sign in to comment.