Encrypt - расшифровывает OpenSSL в PHP только буквами

Я хотел бы хранить адреса электронной почты в базе данных, но, поскольку она является общей, я хотел бы хранить их в зашифрованном виде и расшифровывать при необходимости.
Я думал о шифровании первой части (до @), поэтому я придумал что-то вроде этого:
Реальный адрес электронной почты: myemail@gmail.com Зашифрованный желаемый: 4n095tOA8PpRq5Nw2tIEp8l47@gmail.com

Проблема в том, что когда я использую функцию, подобную этой:

function EncryptVar($sVar){

return  openssl_encrypt($sVar, $this->encryptionMethod, $this->secretHash);

} 

с некоторым секретным хешем и этим следующим методом

$this->secretHash = "25c6c7ff35b9979b151f2136cd1sdftrez";
$this->encryptionMethod = "AES-256-CBC";

Я могу предложить специальные символы в зашифрованной части, поэтому неверный формат адреса электронной почты.
Есть ли способ использовать этот метод, чтобы у меня были только буквы и цифры?

2 ответа

Есть ли способ использовать этот метод, чтобы у меня были только буквы и цифры?

Это отличное место для использования base32-кодировки.

Хорошая реализация этого доступна в этой библиотеке.

Пример, который использует безопасный метод шифрования:

<?php
use ParagonIE\ConstantTime\Base32;

class EmailEncryption
{
    protected $key;

    public function __construct($key)
    {
        if (mb_strlen($key, '8bit') !== 32) {
            throw new Exception('Keys should be 32 bytes generated from /dev/urandom');
        } 
    }

    /**
     * @param string $sVar
     * @return string
     */
    public function encryptVar($sVar)
    {
        $nonce = random_bytes(12);
        $tag = '';
        $encrypted = openssl_encrypt(
            $sVar,
            'aes-256-gcm',
            $this->key,
            OPENSSL_RAW_DATA,
            $nonce,
            $tag
        );
        return Base32::encode($tag . $nonce . $encrypted);
    }

    /**
     * @param string $sVar
     * @return string
     */
    public function decryptVar($sVar)
    {
        $decoded = Base32::decode($sVar);
        $tag = mb_substr($decoded, 0, 16, '8bit');
        $nonce = mb_substr($decoded, 16, 12, '8bit');
        $ciphertext = mb_substr($decoded, 28, null, '8bit');
        $plaintext = openssl_decrypt(
            $ciphertext,
            'aes-256-gcm',
            $this->key,
            OPENSSL_RAW_DATA,
            $nonce,
            $tag
        );
        if (is_bool($plaintext)) {
            throw new Exception('Invalid ciphertext');
        }
        return $plaintext;
    }
}

Использование:

$key = random_bytes(32);
$encrypter = new EmailEncryption($key);

$message = 'test123456789';
$ciphertext = $encrypter->encryptVar($message);
var_dump($ciphertext);
$plaintext = $encrypter->decryptVar($ciphertext);
var_dump($plaintext, $message);

Примечание: для этого требуется PHP 7.1+, но вы получаете аутентифицированное шифрование.

Распространенным способом решения этой проблемы является кодирование / декодирование с использованием base64_encode / base64_decode, Это преобразует ваши двоичные данные в строку ASCII.

Другие вопросы по тегам