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分块处理)