加密 - 只用字母解密PHP中的OpenSSL

时间:2017-05-09 10:53:14

标签: php encryption php-openssl

我想将电子邮件地址存储在数据库中,但由于它是共享的,我希望在需要时将它们加密并解密。
我想到加密它的第一部分(在@之前)所以我想出了类似的东西:
真实的电子邮件: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 个答案:

答案 0 :(得分:0)

解决此问题的常见方法是使用base64_encode / base64_decode进行编码/解码。这会将您的二进制数据转换为ASCII字符串。

答案 1 :(得分:0)

  

有没有办法使用这种方法所以我只有字母和数字?

这是一个使用base32-encoding的好地方。

this library可以很好地实现这一点。

使用安全加密方法的示例:

<?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+,但会为您提供经过身份验证的加密。