温馨提示×

PHP如何在Linux上实现文件加密解密

小樊
39
2025-11-18 14:06:11
栏目: 编程语言

在Linux上使用PHP进行文件的加密和解密,可以采用多种方法。以下介绍两种常用的方法:

  1. 使用OpenSSL扩展
  2. 使用mcrypt扩展(已废弃,推荐使用OpenSSL)

方法一:使用OpenSSL扩展

PHP的openssl_encryptopenssl_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();
}
?>

说明:

  1. 密钥(Key):确保密钥长度符合所选加密算法的要求。例如,AES-256-CBC需要32字节的密钥。
  2. 初始化向量(IV):每次加密使用不同的IV可以增加安全性。IV不需要保密,但必须唯一。
  3. 加密模式AES-256-CBC是常用的加密模式,可以根据需求选择其他模式,如AES-128-CBCAES-256-ECB等。
  4. 错误处理:示例中使用了异常处理,可以根据需要调整错误处理方式。

方法二:使用mcrypt扩展(已废弃)

注意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以获得更好的支持和功能。

安全性建议

  1. 密钥管理:确保密钥的安全存储,避免硬编码在代码中。可以使用环境变量、配置文件或密钥管理服务来管理密钥。
  2. 文件权限:加密后的文件应设置适当的文件权限,防止未授权访问。
  3. 错误处理:避免在错误信息中泄露敏感信息,如密钥或IV。
  4. 加密模式和填充:选择合适的加密模式和填充方式,确保数据的安全性。例如,使用AES-256-CBC配合PKCS5填充。

总结

在Linux环境下使用PHP进行文件加密和解密,推荐使用OpenSSL扩展,因为它功能强大、支持多种算法和模式,并且是当前PHP官方支持的标准方法。通过合理管理密钥和文件权限,可以确保数据的安全性。

0