【问题标题】:Using PHP to encrypt image for storage in MySQL BLOB then decrypt and print使用 PHP 加密图像以存储在 MySQL BLOB 中,然后解密并打印
【发布时间】:2018-03-05 22:25:25
【问题描述】:

我正在尝试获取上传的图像,对图像进行加密,将其存储在 MySQL 中,然后在授权人员请求查看时对其进行解密以显示。

这是我目前的加密方式:

$image = addslashes(file_get_contents($_FILES['users_image']['tmp_name']));
$enc_image = encrypt($image, "long secret random key");

然后我将$enc_image 存储在 MySQL BLOB 字段中。当我尝试解密并打印它时,如下所示:

$img = decrypt($rec['file'], "long secret random key");
echo '<img src="data:image/jpeg;base64,'.base64_encode($img).'"/>';

我正在使用来自this Stackoverflow answer 的这段代码,我在输出中看到了解密的 base-64 文本,但它没有通过 HTML 显示。以下是试图恢复的加密图像示例:https://pastebin.com/miDCP3Gz

注意:我的“长秘密随机密钥”包括一个散列随机唯一盐,但我确信我使用相同的字符串进行加密和解密。

知道为什么不能正确显示吗?

【问题讨论】:

    标签: php mysql encryption cryptography blob


    【解决方案1】:
    1. 确保您的图像足够小或您的存储位置足够大。如果你有超过 65kB 的东西,你需要一个 longblob 而不是 blob。超过该大小的任何内容都将被截断并丢失。

    2. 在插入数据库之前将斜杠移到右侧,而不是在加密之前。单引号(或双引号,具体取决于您使用的引号)为 MySQL 引擎指定字符串的开头和结尾。 addlashes 函数转义这些和其他特殊字符,以防止它们混淆 MySQL 引擎。它在加密之前将记录添加到数据库中的事实仅仅是随机机会。

    3. 您应该知道这些图像作为临时文件保存在服务器上。除非采取特殊预防措施,否则其中的数据将保留在 HDD 上的空闲空间中。攻击者可以使用取证或恢复工具轻松检索它。

    标记:

    <html>
    <head><title>Picture</title></head>
    <body>
        <form enctype="multipart/form-data" action="file.php" method="post">
            <input type="hidden" name="MAX_FILE_SIZE" value="600000" />
            <input type="file" name="users_image"/>
            <input type="submit" text="Upload">
        </form>
    <?
    
        if($_SERVER['REQUEST_METHOD'] === 'POST')
        {
    
            $image = file_get_contents($_FILES['users_image']['tmp_name']);
            //encrypt
            $cipher = "aes-128-cbc";
            $ivlen = openssl_cipher_iv_length($cipher);
            $iv = openssl_random_pseudo_bytes($ivlen);
            $key = openssl_random_pseudo_bytes(128);
            $ciphertext = openssl_encrypt($image, $cipher, $key, $options=0, $iv);
    
            //add to DB
            $mysqli = mysqli_connect("localhost","testu","","test");
            $query = "INSERT INTO blobtbl(pics) VALUES (\"" . addslashes($ciphertext) ."\")";
            $mysqli->query($query);
            $id = mysqli_insert_id($mysqli);
    
            //retrieve from DB
            $sql = "SELECT * FROM blobtbl WHERE id = $id";
            $res = $mysqli->query($sql);
            $row=mysqli_fetch_assoc($res);
            $newciphertext = $row['pics'];
    
            //decrpyt and display
            $img = openssl_decrypt($newciphertext, $cipher, $key, $options=0, $iv);
            echo '<img src="data:image/jpeg;base64,'.base64_encode($img).'"/>';
            echo "<br>Did it work?";
        }
    ?>
    </body>
    </html>
    

    【讨论】:

      【解决方案2】:

      删除加密阶段的附加斜线。

      【讨论】:

      • 当我删除它甚至没有正确插入到数据库中。
      • 什么是 Apache 错误日志或 BD 错误日志?你的加密库或方法是什么?
      猜你喜欢
      • 2020-10-04
      • 2015-04-19
      • 2015-01-01
      • 2015-05-09
      • 1970-01-01
      • 2014-09-16
      • 2012-08-16
      • 2012-08-01
      • 2018-10-29
      相关资源
      最近更新 更多