3

I need to encrypt the customer data in the database, so if the database is hacked. the Hacker cannot access my customers (Customer privacy).

I need to encrypt the customer data just before saving it into the database so that I don't need to handle validation errors. As like this also I need to decrypt the customer data just after fetched from the database and shown on my site (Frontend & adminhtml).

I know how to encrypt and decrypt using Magento\Framework\Encryption\EncryptorInterface

I have tried the Around plugin for Customer Model (set & get), but this doesn't work in an expected way.

5
  • Which concrete data do you want to encrypt? Jun 7 at 10:11
  • @RaulSanchez I'd like to encrypt all the data in the customer table to encrypt. simple we can say it for customer privacy (name, email,date of birth & Address)
    – Sathya
    Jun 7 at 10:29
  • But you'd consider then redefining some database fields, where that data has to be stored, as the format will be different Jun 7 at 10:35
  • Why do you need to encrypt the data in the database? What happens if the Hacker hacks your webserver? Or exploits Magento? Those are far more likely than the Hacker directly accessing your database. If there is a specific threat or certification that you are concerned with, then be very specific with what it is. "Hacker hacking the database" sounds like a phrase someone unfamiliar with the industry would use. Whoever told you that needs to be specific with what certification your Magento application needs, and it won't begin nor end with encrypting specific database fields.
    – dotancohen
    Jun 30 at 7:40
  • @dotancohen We developer, develop the feature asked by the client. My client wants to encrypt the customer details in the Database that's it. The phrase He used while I asked about the purpose but also HE want this implementation for another purpose, which I can't expose as its NDA.
    – Sathya
    Jun 30 at 10:58

2 Answers 2

5
+50

Magento has a lot of logic to work with customer data directly with placeholders, etc. Unfortunately it's very difficult (and in some cases impossible properly) to encrypt all customer and address data.

For example to encrypt/decrypt email you need to support the same crypt algorytm for all rows (for cover unique email, load by email) and overwrite all places where the system checks customer by email.

Another example to encrypt/decrypt firstname you need to cover all places where system works with it in SQL and also you cannot use search by for those fields.

You should understand that you need to fix table column type or eav metadata for any encrypted attributes

Following example more as concept how you can encrypt/decrypt some data for customer

app/code/Acme/StackExchange/etc/di.xml

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Customer\Model\Customer">
        <plugin name="Acme_StackExchange_Plugin_Customer_Model_CustomerPlugin"
                type="Acme\StackExchange\Plugin\Customer\Model\CustomerPlugin" sortOrder="10"/>
    </type>
    <type name="Magento\Customer\Model\ResourceModel\Customer\Collection">
        <plugin name="Acme_StackExchange_Plugin_Customer_Model_ResourceModel_Customer_CollectionPlugin"
                type="Acme\StackExchange\Plugin\Customer\Model\ResourceModel\Customer\CollectionPlugin" sortOrder="10"/>
    </type>
</config>

app/code/Acme/StackExchange/Helper/Customer.php

<?php
declare(strict_types=1);

namespace Acme\StackExchange\Helper;

use Magento\Framework\App\Helper\AbstractHelper;

class Customer extends AbstractHelper
{
    public function getAttributes(): array
    {
        return [
            'middlename',
        ];
    }
}

app/code/Acme/StackExchange/Plugin/Customer/Model/CustomerPlugin.php

<?php
declare(strict_types=1);

namespace Acme\StackExchange\Plugin\Customer\Model;

use Acme\StackExchange\Helper\Customer as CustomerHelper;
use Magento\Customer\Model\Customer;
use Magento\Framework\DataObject;
use Magento\Framework\Encryption\EncryptorInterface;

class CustomerPlugin
{
    /**
     * @var EncryptorInterface
     */
    protected $encryptor;

    /**
     * @var CustomerHelper
     */
    protected $helper;

    public function __construct(
        EncryptorInterface $encryptor,
        CustomerHelper $helper
    ) {
        $this->encryptor = $encryptor;
        $this->helper    = $helper;
    }

    protected function encrypt(DataObject $object): void
    {
        foreach ($this->helper->getAttributes() as $attributeCode) {
            $value = $object->getData($attributeCode);
            if ($value) {
                $object->setData($attributeCode, $this->encryptor->encrypt($value));
            }
        }
    }

    protected function decrypt(DataObject $object): void
    {
        foreach ($this->helper->getAttributes() as $attributeCode) {
            $value = $object->getData($attributeCode);
            if ($value) {
                try {
                    $object->setData($attributeCode, $this->encryptor->decrypt($value));
                } catch (\Exception $e) {
                    // value is not encrypted or something wrong with encrypted data
                }
            }
        }
    }

    public function afterBeforeSave(Customer $subject): void
    {
        $this->encrypt($subject);
    }

    public function afterAfterSave(Customer $subject): void
    {
        $this->decrypt($subject);
    }

    public function afterAfterLoad(Customer $subject): void
    {
        $this->decrypt($subject);
    }
}

app/code/Acme/StackExchange/Plugin/Customer/Model/ResourceModel/Customer/CollectionPlugin.php

<?php

namespace Acme\StackExchange\Plugin\Customer\Model\ResourceModel\Customer;

use Acme\StackExchange\Helper\Customer as CustomerHelper;
use Magento\Customer\Model\ResourceModel\Customer\Collection;
use Magento\Framework\Encryption\EncryptorInterface;

class CollectionPlugin
{
    /**
     * @var EncryptorInterface
     */
    protected $encryptor;

    /**
     * @var CustomerHelper
     */
    protected $helper;

    /**
     * @var bool
     */
    protected $isLoaded = false;

    public function __construct(
        EncryptorInterface $encryptor,
        CustomerHelper $helper
    ) {
        $this->encryptor = $encryptor;
        $this->helper    = $helper;
    }

    public function beforeLoad(Collection $subject, $printQuery = false, $logQuery = false): array
    {
        $this->isLoaded = $subject->isLoaded();

        return [$printQuery, $logQuery];
    }

    public function afterLoad(Collection $subject, Collection $result): Collection
    {
        if (!$this->isLoaded) {
            $this->isLoaded = true;

            foreach ($subject->getItems() as $object) {
                foreach ($this->helper->getAttributes() as $attributeCode) {
                    $value = $object->getData($attributeCode);
                    if ($value) {
                        try {
                            $object->setData($attributeCode, $this->encryptor->decrypt($value));
                        } catch (\Exception $e) {
                            // value is not encrypted or something wrong with encrypted data
                        }
                    }
                }
            }
        }

        return $result;
    }
}
-1

Magento 2’s encryption and decryption use Magento\Framework\Encryption\EncryptorInterface, which is implemented by Magento\Framework\Encryption\Encryptor class. protected $encryptor;

public function __construct(
   Context $context,
   \Magento\Framework\Encryption\EncryptorInterface $encryptor
) {
   $this->encryptor = $encryptor;
   parent::__construct($context);
}

/**
* Encrypt data
*/
public function encrypt()
{
   $password = ""magenest"";
   $encrypt =  $this->encryptor->encrypt($password);
   return $encrypt
}

/**
* Decrypt value
*/
public function decrypt($value)
{
   return $this->encryptor->decrypt($value);
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.