用PHP加密解密文件:SVG或XML

用PHP加密解密文件:SVG或XML,php,xml,svg,encryption,Php,Xml,Svg,Encryption,我使用这两个函数来加密/解密文件: 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 ($st

我使用这两个函数来加密/解密文件:

    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…”。如图所示:


您可能直接从中复制了代码。但是:正如它在同一页上所说的,这段代码有几个问题。基本上,使用
md5
进行密钥派生远远不是最优的。有关完整说明,请参阅。此和加密筛选器已弃用(请参阅同一链接),我建议放弃这种类型的加密

我还建议使用一些经过测试的PHP加密库,如。这也将集成到php7本身中。()

回到主题:您看到的是加密填充。为了使分组密码(在您的例子中是DES)能够工作,每个块必须具有算法给定的大小。由于大多数数据不关心块大小,因此算法必须应用某种填充

解密时,还将收到填充值。要获得输出值,需要在之后删除填充。在您的情况下,这将是修剪尾部
NUL
charachters。它已经在文档中(感谢您指出这一点)


您使用什么来读取和写入文件(以及什么标志)?我道歉。我没有给出正确的函数。我必须修改我的问题,但我不能编辑它。加密过滤器在新的PHP版本中不推荐使用:from,
$data=rtrim(stream\u get\u contents($fp))//修剪空填充
谢谢@James这就是问题所在。现在它起作用了
$data = rtrim(stream_get_contents($fp)); //trims off null padding