在Linux上使用PHP进行文件的加密和解密,可以采用多种方法。以下介绍两种常用的方法:
PHP的openssl_encrypt和openssl_decrypt函数提供了强大的加密和解密功能,支持多种加密算法(如AES、DES等)和模式(如CBC、ECB等)。以下是一个示例:
<?php
// 加密函数
function encryptFile($source, $destination, $key, $method = 'AES-256-CBC') {
// 生成随机的初始化向量(IV)
$ivLength = openssl_cipher_iv_length($method);
$iv = openssl_random_pseudo_bytes($ivLength);
// 加密数据
$encrypted = openssl_encrypt(file_get_contents($source), $method, $key, OPENSSL_RAW_DATA, $iv);
// 将IV和加密数据写入目标文件
if (file_put_contents($destination, $iv . $encrypted) === false) {
throw new Exception("无法写入加密文件");
}
}
// 解密函数
function decryptFile($source, $destination, $key, $method = 'AES-256-CBC') {
// 读取IV和加密数据
$data = file_get_contents($source);
if ($data === false) {
throw new Exception("无法读取加密文件");
}
// 分离IV和加密数据
$ivLength = openssl_cipher_iv_length($method);
if ($ivLength <= 0 || $ivLength > strlen($data)) {
throw new Exception("无效的IV长度");
}
$iv = substr($data, 0, $ivLength);
$encrypted = substr($data, $ivLength);
// 解密数据
$decrypted = openssl_decrypt($encrypted, $method, $key, OPENSSL_RAW_DATA, $iv);
if ($decrypted === false) {
throw new Exception("解密失败");
}
// 将解密后的数据写入目标文件
if (file_put_contents($destination, $decrypted) === false) {
throw new Exception("无法写入解密文件");
}
}
// 使用示例
$key = 'your-secret-key'; // 16、24或32字节长度的密钥
$sourceFile = '/path/to/source/file.txt';
$encryptedFile = '/path/to/encrypted/file.enc';
$decryptedFile = '/path/to/decrypted/file_decrypted.txt';
try {
// 加密文件
encryptFile($sourceFile, $encryptedFile, $key);
echo "文件加密成功。\n";
// 解密文件
decryptFile($encryptedFile, $decryptedFile, $key);
echo "文件解密成功。\n";
} catch (Exception $e) {
echo "错误: " . $e->getMessage();
}
?>
AES-256-CBC是常用的加密模式,可以根据需求选择其他模式,如AES-128-CBC、AES-256-ECB等。注意:mcrypt扩展在PHP 7.1.0中被废弃,并在PHP 7.2.0中移除。建议优先使用OpenSSL扩展。
如果你的PHP环境仍在使用mcrypt,以下是一个简单的示例:
<?php
// 加密函数
function mcryptEncryptFile($source, $destination, $key, $cipher = MCRYPT_RIJNDAEL_256) {
// 生成IV
$iv = mcrypt_create_iv(mcrypt_get_iv_size($cipher, MCRYPT_MODE_CBC), MCRYPT_RAND);
// 加密数据
$encrypted = mcrypt_encrypt($cipher, $key, file_get_contents($source), MCRYPT_MODE_CBC, $iv);
// 将IV和加密数据写入目标文件
if (file_put_contents($destination, $iv . $encrypted) === false) {
throw new Exception("无法写入加密文件");
}
}
// 解密函数
function mcryptDecryptFile($source, $destination, $key, $cipher = MCRYPT_RIJNDAEL_256) {
// 读取IV和加密数据
$data = file_get_contents($source);
if ($data === false) {
throw new Exception("无法读取加密文件");
}
// 分离IV和加密数据
$ivLength = mcrypt_get_iv_size($cipher, MCRYPT_MODE_CBC);
if ($ivLength <= 0 || $ivLength > strlen($data)) {
throw new Exception("无效的IV长度");
}
$iv = substr($data, 0, $ivLength);
$encrypted = substr($data, $ivLength);
// 解密数据
$decrypted = mcrypt_decrypt($cipher, $key, $encrypted, MCRYPT_MODE_CBC, $iv);
if ($decrypted === false) {
throw new Exception("解密失败");
}
// 去除填充(PKCS5)
$decrypted = rtrim($decrypted, "\0");
// 将解密后的数据写入目标文件
if (file_put_contents($destination, $decrypted) === false) {
throw new Exception("无法写入解密文件");
}
}
// 使用示例
$key = 'your-secret-key'; // 16、24或32字节长度的密钥
$sourceFile = '/path/to/source/file.txt';
$encryptedFile = '/path/to/encrypted/file.enc';
$decryptedFile = '/path/to/decrypted/file_decrypted.txt';
try {
// 加密文件
mcryptEncryptFile($sourceFile, $encryptedFile, $key);
echo "文件加密成功。\n";
// 解密文件
mcryptDecryptFile($encryptedFile, $decryptedFile, $key);
echo "文件解密成功。\n";
} catch (Exception $e) {
echo "错误: " . $e->getMessage();
}
?>
mcrypt已被废弃,强烈建议迁移到OpenSSL扩展。MCRYPT_RIJNDAEL_256等同于AES-256,但推荐使用OpenSSL以获得更好的支持和功能。AES-256-CBC配合PKCS5填充。在Linux环境下使用PHP进行文件加密和解密,推荐使用OpenSSL扩展,因为它功能强大、支持多种算法和模式,并且是当前PHP官方支持的标准方法。通过合理管理密钥和文件权限,可以确保数据的安全性。