是否可以使用php-openssl加密图像文件?

时间:2019-04-06 11:35:18

标签: php encryption php-openssl

我正在制作一个Web服务器,可以使用php上传和下载所有类型的文件。(服务器os是Windows) 上载和下载文件时,将使用AES对其进行加密和解密。 我已经搜索过了,而且已经做到了。 但它仅适用于.pdf,.csv,.txt,.pptx文件。

当我尝试打开已解密的.jpg,.png,.zip,.xlsx文件时,无法正常打开。我看不到图片。

// File encryption code
$filename = $_FILES['user_file']["name"];
$key = '1234';
$iv = '12dasdq3g5b2434b';
$file = fopen('filePath', 'rb');
$fileData = fread($file, filesize('filePath'));
fclose($file);
$encryptedData = openssl_encrypt($fileData, "AES-256-CBC", $key, 0, $iv);
$fileToWrite = fopen('filePath', 'wb');
fwrite($fileToWrite, $encryptedData);
fclose($fileToWrite);

// File decryption code
$key = '1234';
$iv = '12dasdq3g5b2434b';
$file = fopen('filePath', 'rb');
$fileData = fread($file, filesize('filePath'));
fclose($file);
$decryptedData = openssl_decrypt($fileData, "AES-256-CBC", $key, 0,  $iv);
header("Pragma: public");
header("Pragma: no-cache");
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Expires: 0");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"" . $filename . "\";");
$size = strlen($decryptedData);
header("Content-Length: " . $size);
echo $decryptedData;    
die;

我不知道为什么它不适用于图像文件。 我的代码有问题吗?

1 个答案:

答案 0 :(得分:2)

问题出在标头Content-Type: application/octet-stream中的MIME类型,具体取决于文件格式还是image/jpeg之类的东西。如果您不能确定静态的mime类型,那么解密后只需要获取文件的前4个字节,然后得出其MIME类型,例如:(我为Node.JS做的此开关,您可以进行一些小的更改为您,但MagicNumbers是通用的)

switch (signature) {
    case '89504E47':
        return 'image/png'
    case '47494638':
        return 'image/gif'
    case '25504446':
        return 'application/pdf'
    case 'FFD8FFDB':
    case 'FFD8FFE0':
        return 'image/jpeg'
    case '504B0304':
        return 'application/zip'
    default:
        return 'Unknown filetype'
}

其他:我发现这种加密方式更加有效(对我而言非常有效)

file_put_contents ('./file.encrypted',openssl_encrypt ($source, $method, $pass, true, $iv));
$exec = "openssl enc -".$method." -d -in file.encrypted -nosalt -nopad -K ".strtohex($pass)." -iv ".strtohex($iv);