PHP using mcrypt and store the encrypted in MySQL

2019-04-02 04:11发布

I am using Mcrypt to encrypt some strings.

After that I store them in my database, but in my database it looks like "??f??R?????h$", because many special chars are replaced by a '?'.

Do I have to use a special charset or is there another simple way?

Regards, Cr41s3

标签: php mysql mcrypt
3条回答
聊天终结者
2楼-- · 2019-04-02 04:37

1) To store binary stuff in mysql, use type BINARY/VARBINARY/BLOB instead of CHAR/VARCHAR/TEXT

2) When saving binary data to DB, use a method that won't apply any processing to the 'text' (you don't want to have your binary data processed as it were some string). Best bet is to use prepared statements of mysqli or PDO.

3) If you, for some reason, want to 'see binary stuff in DB', you will need to make them somewhat readable. Like using SELECT hex(binary_field) or SELECT TO_BASE64(binary_field)

4) If you refuse to use BLOB and prepared statements, well, to store binary data in mysql, first convert them using base64_encode(), so it will contain only printable characters.

查看更多
Juvenile、少年°
3楼-- · 2019-04-02 04:48

I think you might be saving the encrypted string's bytes directly into mysql database.

You could do something like this to solve your problem:

  • Encryption: Orignal Text > MCrypt Encrypt > Base64 Encode > Store as Plain Text in MySQL

  • Decryption: Load encrypted base64 encoded text from MySQL > Base64 Decode > MCrypt Decrypt -> Orignal Text

This is how I would do it. Create a class to do encryption/decryption:

<?php

class cipher
{
    private $securekey;
    private $iv_size;

    function __construct($textkey)
    {
        $this->iv_size = mcrypt_get_iv_size(
            MCRYPT_RIJNDAEL_128,
            MCRYPT_MODE_CBC
        );
        $this->securekey = hash(
            'sha256',
            $textkey,
            TRUE
        );
    }

    function encrypt($input)
    {
        $iv = mcrypt_create_iv($this->iv_size);
        return base64_encode(
            $iv . mcrypt_encrypt(
                MCRYPT_RIJNDAEL_128,
                $this->securekey,
                $input,
                MCRYPT_MODE_CBC,
                $iv
            )
        );
    }

    function decrypt($input)
    {
        $input = base64_decode($input);
        $iv = substr(
            $input,
            0,
            $this->iv_size
        );
        $cipher = substr(
            $input,
            $this->iv_size
        );
        return trim(
            mcrypt_decrypt(
                MCRYPT_RIJNDAEL_128,
                $this->securekey,
                $cipher,
                MCRYPT_MODE_CBC,
                $iv
            )
        );
    }
}

?>

Then use it like this:

// Usage
$cipher = new cipher('my-secret-key');
$orignal_text = 'my secret message';
$encrypted_text = $cipher->encrypt($orignal_text);   // store this in db
$decrypted_text = $cipher->decrypt($encrypted_text); // load $encrypted_text from db

// Debug
echo "<pre>";
echo "Orignal Text  : $orignal_text\r\n";
echo "Encrypted Text: $encrypted_text\r\n";
echo "Decrypted Text: $decrypted_text";
echo "</pre>";

This respectively outputs the following:

Orignal Text  : my secret message
Encrypted Text: Z21ifr5dHEdE9nO8vaDWb9QkjooqCK4UI6D/Ui+fkpmXWwmxloy8hM+7oimtw1wE
Decrypted Text: my secret message
查看更多
甜甜的少女心
4楼-- · 2019-04-02 04:50

I now used the method by Ryan Vincent:

I 'base64_encode' encrypted strings before storing them in the database. It is a very 'safe' way of encoding 'binary strings'. They can be passed around between systems over HTML, email etc. and will never be changed.

I first encode everything with base64_encode and then store it in my database.

查看更多
登录 后发表回答