【问题标题】:How to encrypt/decrypt files with php (mcrypt)?如何使用 php (mcrypt) 加密/解密文件?
【发布时间】:2012-07-27 19:10:48
【问题描述】:

令我惊讶的是,我在网络上没有找到任何解释如何仅使用标准 php 组件加密文件的代码 sn-p、建议或教程。

所以我在问您的建议:如何仅使用 mcrypt 和 php 标准函数来加密/解密文件?我没有使用 gnupg 的选项。不,实际上,我的问题是:如何在不弄乱我的文件的情况下执行上述操作?因为我已经对这些文件进行了加密/解密(使用 mcrypt/AES),它适用于 jpeg、PDF、一些 .doc 文件和有趣的密码保护 .docx 文件。它不适用于不安全的 .docx 文件和许多其他文件类型。

我当前的代码是这样的。基本上,我真的只是打开文件,用 mcrypt/AES 搅拌数据,然后将其写入服务器/让用户下载它。

上传后编码:

// using codeigniter's encryption library, which uses mcrypt and the AES cypher
$this->load->library('encrypt');
$pathandname = $config['upload_path'].$output['content'][$a]['file_name']; 
$theFile = file_get_contents($pathandname);
$fh = fopen($pathandname,'w');
fwrite($fh,$this->encrypt->encode($theFile));
fclose($fh); 

解码和下载:

$this->load->library('encrypt');
$pathandname = $filelocation.$results[0]['encryptedfile']; 
$theFile = file_get_contents($pathandname);
$decrypted = $this->encrypt->decode($theFile);
force_download($filename, $decrypted); // a codeigniter function to force download via headers

【问题讨论】:

  • 到底是什么问题?您当前的方法不起作用吗?或者你有兴趣在没有 CodeIgniter 的情况下如何做吗?如果是后者,为什么不直接阅读相关资料?
  • 不,我想知道如何使用这种方法。但解密文件
  • 不要再使用过时的 CodeIgniter 2 加密库,改用 CodeIgniter 3 的加密库。加密是脆弱的,加密是安全的。

标签: php file encryption mcrypt


【解决方案1】:

如何仅使用 mcrypt 和 php 标准函数加密/解密文件?

好吧,you don't want to use mcrypt。这些天你想用钠。

使用 Sodium(PHP 7.2+、PECL ext/sodium 或 sodium_compat)加密文件

您要查找的相关 API 是 crypto_secretstream

const CUSTOM_CHUNK_SIZE = 8192;

/**
 * @ref https://stackoverflow.com/q/11716047
 */
function encryptFile(string $inputFilename, string $outputFilename, string $key): bool
{
    $iFP = fopen($inputFilename, 'rb');
    $oFP = fopen($outputFilename, 'wb');

    [$state, $header] = sodium_crypto_secretstream_xchacha20poly1305_init_push($key);

    fwrite($oFP, $header, 24); // Write the header first:
    $size = fstat($iFP)['size'];
    for ($pos = 0; $pos < $size; $pos += CUSTOM_CHUNK_SIZE) {
        $chunk = fread($iFP, CUSTOM_CHUNK_SIZE);
        $encrypted = sodium_crypto_secretstream_xchacha20poly1305_push($state, $chunk);
        fwrite($oFP, $encrypted, CUSTOM_CHUNK_SIZE + 17);
        sodium_memzero($chunk);
    }

    fclose($iFP);
    fclose($oFP);
    return true;
}

解密如下:

/**
 * @ref https://stackoverflow.com/q/11716047
 */
function decryptFile(string $inputFilename, string $outputFilename, string $key): bool
{
    $iFP = fopen($inputFilename, 'rb');
    $oFP = fopen($outputFilename, 'wb');

    $header = fread($iFP, 24);
    $state = sodium_crypto_secretstream_xchacha20poly1305_init_pull($header, $key);
    $size = fstat($iFP)['size'];
    $readChunkSize = CUSTOM_CHUNK_SIZE + 17;
    for ($pos = 24; $pos < $size; $pos += $readChunkSize) {
        $chunk = fread($iFP, $readChunkSize);
        [$plain, $tag] = sodium_crypto_secretstream_xchacha20poly1305_pull($state, $chunk);
        fwrite($oFP, $plain, CUSTOM_CHUNK_SIZE);
        sodium_memzero($plain);
    }
    fclose($iFP);
    fclose($oFP);
    return true;
}

同时使用这两个函数:

$key = random_bytes(32);
encryptFile('input.txt', 'cipher.txt', $key);
decryptFile('cipher.txt', 'decrypt.txt', $key);

【讨论】:

  • 你能解释一下关键参数和它需要什么值吗?解密时您需要正确的相同密钥吗?
猜你喜欢
  • 2011-01-24
  • 2011-01-27
  • 2015-11-10
  • 2015-09-04
  • 2013-08-13
  • 2013-12-28
  • 2023-03-03
  • 2019-04-13
  • 2014-02-24
相关资源
最近更新 更多