簡體   English   中英

PHP加密較大的文件

[英]PHP Encrypting Larger Files

我正在嘗試加密所有上傳到服務器的文件,而我的方法可以正常工作。 但是我注意到超過100kb的DECRYPTING文件只會返回null,而且我很困惑為什么對這些文件進行加密,而對解密卻沒有。 我的代碼有問題嗎,還是有其他解決方法? php.ini中允許的上傳大小沒有任何問題,upload.php頁面運行得很好,並將文件上傳到服務器。 唯一的問題是文件超過100kb。 我覺得這與PHP中的最大變量長度有關,但是我不確定。

// Encrypt Function
public static function mc_encrypt($encrypt, $key)
{
    $encrypt = serialize($encrypt);
    $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC), MCRYPT_DEV_URANDOM);
    $key = pack('H*', $key);
    $mac = hash_hmac('sha256', $encrypt, substr(bin2hex($key), -32));
    $passcrypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $encrypt.$mac, MCRYPT_MODE_CBC, $iv);
    $encoded = base64_encode($passcrypt).'|'.base64_encode($iv);
    return $encoded;
}

// Decrypt Function
public static function mc_decrypt($decrypt, $key)
{
    $decrypt = explode('|', $decrypt.'|');
    $decoded = base64_decode($decrypt[0]);
    $iv = base64_decode($decrypt[1]);
    if(strlen($iv)!==mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC)){ return false; }
    $key = pack('H*', $key);
    $decrypted = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $decoded, MCRYPT_MODE_CBC, $iv));
    $mac = substr($decrypted, -64);
    $decrypted = substr($decrypted, 0, -64);
    $calcmac = hash_hmac('sha256', $decrypted, substr(bin2hex($key), -32));
    if($calcmac!==$mac){ return false; }
    $decrypted = unserialize($decrypted);
    return $decrypted;
}

應該在哪里解密:

try
    {
        $server = $db->prepare("SELECT * FROM `servers` WHERE `ServerIP` = :ip LIMIT 1");
        $server->execute([ ":ip" => $ip ]);
        $server = $server->fetch();
        $sftp = new SFTPConnection($server['ServerIP'], intval($server['ServerPort']));
        $sftp->login($server['ServerUser'], $server['ServerPassword']);
        $fileData = $sftp->receiveFile($path);

        //print $fileData;

        header('Content-type: text/plain');
        $fileName = $file['FileName'];
        header("Content-Disposition: attachment; filename=$fileName");

        //print $fileData; (returns the encrypted version)
        $fileData = Encryption::mc_decrypt($fileData, $file['EncryptionKey']);

        print $fileData; // (returns null on larger files)
    }
    catch (Exception $e)
    {
        echo $e->getMessage() . "\n";
    }

我不確定是什么問題,但是我知道解決方案。 首先,您可能想讀入文件。 您不想將整個電影存儲在RAM中。 因此,您可以做的是將SFTP連接視為流:

根據此處的示例代碼:

$connection = ssh2_connect('shell.example.com', 22);
ssh2_auth_password($connection, 'username', 'password');
$sftp = ssh2_sftp($connection);
$stream = fopen("ssh2.sftp://$sftp/path/to/file", 'rb');

請注意,我使用'rb'強制執行二進制模式。

因此,現在您可以從流中讀取塊,唯一需要做的就是對流進行加密/解密。 實際上,Mcrypt使用過濾器實現來提供此功能

至於HMAC, 您也可以流式傳輸 您可能要為其創建過濾器 -我找不到。

現在,您可以流式傳輸所有內容,繼續進行實施。


安全說明:

  • mcrypt是一個舊的庫,不應該再使用;
  • 如果要使用AES,請使用MCRYPT_RIJNDAEL_128而不是MCRYPT_RIJNDAEL_256(256是塊大小,而不是密鑰大小,密鑰大小由-等待它-提供的密鑰的大小確定);
  • HMAC是安全的,但應在密文和IV上執行;
  • 這不是完整的傳輸協議-但這與通過sftp發送文件無關緊要。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM