我试图加密上传到服务器的所有文件,我的方法也可以;但是我注意到超过100kb的DECRYPTING文件只返回null,我很困惑为什么加密对这些文件起作用,但解密却没有。我的代码有问题,还是有另一种方法? php.ini中允许的上传大小没有任何问题,upload.php页面工作正常,并将文件上传到服务器。唯一的问题是文件超过100kb。我觉得它与PHP中的max变量长度有关,但我不确定。
// 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";
}
答案 0 :(得分:1)
我不确定问题是什么,但我确实知道解决方案。首先,你可能想要在chucks中读取文件。你不想存储,例如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 does actually provide this functionality using a filter implementation
至于HMAC,you can stream that as well。你可能想要create a filter for it - 我找不到一个。
现在您可以流式传输所有内容,然后继续实施。
安全说明: