Where to encrypt/decrypt my data?

后端 未结 3 1298
情深已故
情深已故 2021-01-31 23:41

I\'m using Symfony 2 with Doctrine 2.

I need to encrypt a field in my entity using an encryption service, and I\'m wondering where should I put this logic.

I\'m

相关标签:
3条回答
  • 2021-02-01 00:09

    To expand on richsage and targnation's great answers, one way to inject a dependency (e.g., cypto service) into a custom Doctrine mapping type, could be to use a static property and setter:

    // MyBundle/Util/Crypto/Types/EncryptedString.php
    class EncryptedString extends StringType
    {
        /** @var \MyBundle\Util\Crypto */
        protected static $crypto;
    
        public static function setCrypto(Crypto $crypto)
        {
            static::$crypto = $crypto;
        }
    
        public function convertToDatabaseValue($value, AbstractPlatform $platform)
        {
            $value = parent::convertToDatabaseValue($value, $platform);
            return static::$crypto->encrypt($value);
        }
    
        public function convertToPHPValue($value, AbstractPlatform $platform)
        {
            $value = parent::convertToPHPValue($value, $platform);
            return static::$crypto->decrypt($value);
        }
    
        public function getName()
        {
            return 'encrypted_string';
        }
    }
    

    Configuration would look like this:

    // MyBundle/MyBundle.php
    class MyBundle extends Bundle
    {
        public function boot()
        {
            /** @var \MyBundle\Util\Crypto $crypto */
            $crypto = $this->container->get('mybundle.util.crypto');
            EncryptedString::setCrypto($crypto);
        }
    }
    
    # app/Resources/config.yml
    doctrine:
        dbal:
            types:
                encrypted_string: MyBundle\Util\Crypto\Types\EncryptedString
    
    # MyBundle/Resources/config/services.yml
    services:
        mybundle.util.crypto:
            class: MyBundle\Util\Crypto
            arguments: [ %key% ]
    
    0 讨论(0)
  • 2021-02-01 00:11

    I don't know if it's the right way at all, but I implemented this recently by creating a custom mapping type, as per the Doctrine docs. Something like the following:

    class EncryptedStringType extends TextType
    {
        const MYTYPE = 'encryptedstring'; // modify to match your type name
    
        public function convertToPHPValue($value, AbstractPlatform $platform)
        {
            return base64_decode($value);
        }
    
        public function convertToDatabaseValue($value, AbstractPlatform $platform)
        {
            return base64_encode($value);
        }
    
        public function getName()
        {
            return self::MYTYPE;
        }
    }
    

    I registered this type in my bundle class:

    class MyOwnBundle extends Bundle
    {
        public function boot()
        {
            $em = $this->container->get("doctrine.orm.entity_manager");
            try
            {
                Type::addType("encryptedstring", "My\OwnBundle\Type\EncryptedStringType");
    
                $em->
                    getConnection()->
                    getDatabasePlatform()->
                    registerDoctrineTypeMapping("encryptedstring", "encryptedstring");
            } catch (\Doctrine\DBAL\DBALException $e)
            {
                // For some reason this exception gets thrown during
                // the clearing of the cache. I didn't have time to
                // find out why :-)
            }
        }
    }
    

    and then I was able to reference it when creating my entities, eg:

    /**
     * @ORM\Column(type="encryptedstring")
     * @Assert\NotBlank()
     */
    protected $name;
    

    This was a quick implementation, so I'd be interested to know the correct way of doing it. I presume also that your encryption service is something available from the container; I don't know how feasible/possible it would be to pass services into custom types this way either... :-)

    0 讨论(0)
  • 2021-02-01 00:21

    richsage's answer was pretty good, except I wouldn't register the custom type in the bundle class file. It's recommended that you use the config.yml like so:

    # ./app/config/confi
    doctrine:
        dbal:
            driver:   "%database_driver%"
            {{ etc, etc }}
            types:
                encrypted_string: MyCompany\MyBundle\Type\EncryptedStringType
    

    Then just make sure in your EncryptedStringType class you specify the getName function to return encrypted_string.

    Now in your model definition (or annotation) you can use the encrypted_string type.

    0 讨论(0)
提交回复
热议问题