PHP 文件加密上传下载完整实现

```html PHP 文件加密上传下载完整实现

PHP 文件加密上传下载完整实现

在敏感业务场景中(如医疗、金融、政务系统),文件需在传输与存储环节全程加密。本文提供基于 OpenSSL 的轻量级、安全可落地的 PHP 加密文件处理方案。

核心思路

✅ 使用 AES-256-CBC 对称加密(PHP 7.2+ 原生支持) ✅ 上传时加密后存为 `.enc` 文件,附带随机 IV(初始向量) ✅ 下载时解密并设正确 Content-Disposition 头 ✅ 密钥通过环境变量或配置中心管理(示例中用常量模拟)

关键代码实现

<?php
// config.php —— 安全密钥(生产环境请使用 getenv() 或 Vault)
define('ENCRYPTION_KEY', '32-byte-secret-key-for-aes-256-cbc'); // 必须32字节

function encryptFile($inputPath, $outputPath) {
    $ivlen = openssl_cipher_iv_length($cipher = "AES-256-CBC");
    $iv = openssl_random_pseudo_bytes($ivlen);
    $key = substr(hash('sha256', ENCRYPTION_KEY), 0, 32);
    
    $encrypted = openssl_encrypt(file_get_contents($inputPath), $cipher, $key, 0, $iv);
    file_put_contents($outputPath, $iv . $encrypted); // IV前置,解密时读取
}

function decryptFile($inputPath, $outputPath) {
    $ivlen = openssl_cipher_iv_length($cipher = "AES-256-CBC");
    $data = file_get_contents($inputPath);
    $iv = substr($data, 0, $ivlen);
    $encrypted = substr($data, $ivlen);
    $key = substr(hash('sha256', ENCRYPTION_KEY), 0, 32);
    
    $decrypted = openssl_decrypt($encrypted, $cipher, $key, 0, $iv);
    file_put_contents($outputPath, $decrypted);
}
?>

上传与下载接口示例

<!-- upload.php -->
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['file'])) {
    $tmp = $_FILES['file']['tmp_name'];
    $name = basename($_FILES['file']['name']);
    $encPath = 'uploads/' . $name . '.enc';
    
    encryptFile($tmp, $encPath);
    echo json_encode(['success' => true, 'download_url' => 'download.php?file=' . urlencode($name)]);
}
?>
<!-- download.php -->
<?php
if (isset($_GET['file'])) {
    $filename = basename($_GET['file']);
    $encPath = 'uploads/' . $filename . '.enc';
    
    if (file_exists($encPath)) {
        $decPath = sys_get_temp_dir() . '/' . uniqid() . '_' . $filename;
        decryptFile($encPath, $decPath);
        
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename="' . $filename . '"');
        header('Content-Length: ' . filesize($decPath));
        readfile($decPath);
        unlink($decPath); // 即时清理临时解密文件
        exit;
    }
}
http_response_code(404);
echo '文件不存在';
?>
⚠️ 安全提醒: • 永远不要将密钥硬编码在代码中(改用 getenv('APP_ENCRYPTION_KEY')) • 上传目录需禁止 Web 直接访问(如 Nginx 中配置 location ^~ /uploads/ { deny all; }) • 建议配合 HTTPS + 文件哈希校验,防范中间人篡改 • 大文件请改用流式加解密(fopen+openssl_encrypt分块处理)
通过以上实现,您已具备端到端加密能力:文件在磁盘以密文存在,仅在用户下载瞬间内存解密,兼顾安全性与实用性。加密不是银弹,但它是构建可信数据链路的第一道坚实防线。 ```