Ticker

6/recent/ticker-posts

Encrypt the logs in Symfony

In case, you want to encrypt data in logs and only you can decrypt that data with the specific algorithm (and secret key).

Create custom Exception: app\src\Security\Encryptor\Exception\EncryptionException.php

namespace App\Security\Encryptor\Exception;

/**
 * Class EncryptionException.
 */
class EncryptionException extends \RuntimeException
{
}

Create EncryptorInterface: app\src\Security\Encryptor\Interfaces\EncryptorInterface.php

namespace App\Security\Encryptor\Interfaces;

use App\Security\Encryptor\Exception\EncryptionException;

interface EncryptorInterface
{
    /**
     * @param string $data
     *
     * @throws EncryptionException
     *
     * @return string
     */
    public function encrypt(string $data): string;

    /**
     * @param string $data
     *
     * @throws EncryptionException
     *
     * @return string
     */
    public function decrypt(string $data): string;
}


Create Encryptor class: app\src\Security\Encryptor\Encryptor.php

namespace App\Security\Encryptor;

use App\Security\Encryptor\Exception\EncryptionException;
use App\Security\Encryptor\Interfaces\EncryptorInterface;

/**
 * Encrypt data using the given cipher method.
 */
class Encryptor implements EncryptorInterface
{
    /**
     * @var string
     */
    private $method;

    /**
     * @var string
     */
    private $secret;

    /**
     * Enryptor constructor.
     *
     * @param string $method
     * @param string $secret
     */
    public function __construct(string $method = 'aes-256-cbc', string $secret = '')
    {
        $this->method = $method;
        $this->secret = $secret;
    }

    /**
     * {@inheritdoc}
     */
    public function encrypt(string $data): string
    {
        $ivSize     = openssl_cipher_iv_length($this->method);
        $iv         = openssl_random_pseudo_bytes($ivSize);
        $cipherText = openssl_encrypt($data, $this->method, $this->secret, OPENSSL_RAW_DATA, $iv);

        if ($cipherText === false) {
            throw new EncryptionException(sprintf('Unexpected failure in openssl_encrypt: %s', openssl_error_string()));
        }

        return base64_encode($iv.$cipherText);
    }

    /**
     * {@inheritdoc}
     */
    public function decrypt(string $data): string
    {
        $data       = base64_decode($data);
        $ivSize     = openssl_cipher_iv_length($this->method);
        $iv         = mb_substr($data, 0, $ivSize, '8bit');
        $cipherText = mb_substr($data, $ivSize, null, '8bit');
        $decrypt    = openssl_decrypt($cipherText, $this->method, $this->secret, OPENSSL_RAW_DATA, $iv);

        if ($decrypt === false) {
            throw new EncryptionException(sprintf('Unexpected failure in openssl_decrypt: %s', openssl_error_string()));
        }

        return $decrypt;
    }
}

Create custom Processor log: app\src\Security\Logger\Processor\ZeroblogProcessor.php

namespace App\Security\Logger\Processor;

use Monolog\Processor\ProcessorInterface;
use App\Security\Encryptor\Interfaces\EncryptorInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;

/**
 * Pseudonymize sensitive data inside log contexts.
 */
class ZeroblogProcessor implements ProcessorInterface
{
    /**
     * @var EncryptorInterface
     */
    private $encryptor;

    /**
     * @var ParameterBagInterface
     */
    private $params;
    /**
     * ZeroblogProcessor constructor.
     *
     * @param EncryptorInterface $encryptor
     */
    public function __construct(EncryptorInterface $encryptor, ParameterBagInterface $params)
    {
        $this->encryptor = $encryptor;
        $this->params = $params;
    }

    /**
     * @param array $record
     *
     * @return array
     */
    public function __invoke(array $record)
    {
        // check encryption flag in environment config variable (env).
        $enc_flag = $this->params->get('app.enc_flag');
        if ($enc_flag === '1') {
            foreach ($record['context'] as $key => $val) {
                $record['message'] = $this->encryptor->encrypt($record['message']);
                break;
            }
        }
        return $record;
    }
}

Edit services.yaml

app\config\services.yaml
parameters:
    app.enc_flag: '%env(ENC_FLAG)%'

and don't forget to put enc_flag in your .env

ENC_FLAG=1

Post a Comment

0 Comments