我使用这两个函数来加密/解密文件:
private function encrypt_file($source,$destination,$passphrase,$stream=NULL) {
// $source can be a local file...
if($stream) {
$contents = $source;
// OR $source can be a stream if the third argument ($stream flag) exists.
}else{
$handle = fopen($source, "rb");
$contents = @fread($handle, filesize($source));
fclose($handle);
}
$iv = substr(md5("\x1B\x3C\x58".$passphrase, true), 0, 8);
$key = substr(md5("\x2D\xFC\xD8".$passphrase, true) . md5("\x2D\xFC\xD9".$passphrase, true), 0, 24);
$opts = array('iv'=>$iv, 'key'=>$key);
$fp = fopen($destination, 'wb') or die("Could not open file for writing.");
stream_filter_append($fp, 'mcrypt.tripledes', STREAM_FILTER_WRITE, $opts);
fwrite($fp, $contents) or die("Could not write to file.");
fclose($fp);
}
private function decrypt_file($file,$passphrase) {
$iv = substr(md5("\x1B\x3C\x58".$passphrase, true), 0, 8);
$key = substr(md5("\x2D\xFC\xD8".$passphrase, true) .
md5("\x2D\xFC\xD9".$passphrase, true), 0, 24);
$opts = array('iv'=>$iv, 'key'=>$key);
$fp = fopen($file, 'rb');
stream_filter_append($fp, 'mdecrypt.tripledes', STREAM_FILTER_READ, $opts);
return $fp;
}
它适用于大多数文件。但是一般来说SVG或XML文件存在问题。例如,SVG文件的解密在最后一行给出了字符“NUL NUL ...”。正如你在这张图片中看到的那样:
答案 0 :(得分:1)
您可能已直接从PHP documentation复制了代码。但是:正如它在同一页面上所说的那样,这段代码存在一些问题。基本上使用md5
进行密钥派生远非最佳。有关完整说明,请参阅http://www.cryptofails.com/post/70059608390/php-documentation-woes。不推荐使用此加密过滤器(请参阅相同链接),我建议放弃这种加密方式。
我还建议使用一些经过测试的PHP加密库,如libsodium-php。这也将集成到php7本身。 (Source)
返回主题:您看到的是加密填充。对于块密码(在您的情况下为DES),每个块必须具有算法给出的大小。由于大多数数据不关心块大小,因此算法必须应用某种填充。
解密时,您还会收到填充值。要获得输出值,您需要在之后删除填充。在你的情况下,这将修剪拖尾NUL
charachters。它已经在文档中了(感谢@James指出这一点)
$data = rtrim(stream_get_contents($fp)); //trims off null padding