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

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

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

在敏感业务场景中(如医疗、金融、政务系统),文件需在传输与存储环节全程加密。本文提供基于 OpenSSL 的轻量级、生产可用方案,兼顾安全性与可维护性。

核心思路

✅ 使用 AES-256-CBC 对称加密(密钥由密码派生) ✅ 上传时加密后存为二进制文件 + JSON 元数据(含 IV、盐值) ✅ 下载时解密并设置正确 Content-Disposition 头

关键代码示例

1. 加密上传(upload.php

<?php
$key = hash_pbkdf2('sha256', $_POST['password'], $salt = random_bytes(16), 100000, 32);
$iv = random_bytes(16);
$encrypted = openssl_encrypt(file_get_contents($_FILES['file']['tmp_name']), 'AES-256-CBC', $key, 0, $iv);

// 存储:加密内容 + 元数据(JSON)
$data = [
    'iv' => bin2hex($iv),
    'salt' => bin2hex($salt),
    'original_name' => $_FILES['file']['name'],
    'mime' => $_FILES['file']['type']
];
file_put_contents("uploads/{$_FILES['file']['name']}.enc", $encrypted);
file_put_contents("uploads/{$_FILES['file']['name']}.meta", json_encode($data));
echo "✅ 上传并加密成功!";
?>

2. 安全下载(download.php

<?php
$filename = basename($_GET['f']);
$encPath = "uploads/{$filename}.enc";
$metaPath = "uploads/{$filename}.meta";

if (!file_exists($encPath) || !file_exists($metaPath)) die('文件不存在');

$meta = json_decode(file_get_contents($metaPath), true);
$key = hash_pbkdf2('sha256', $_GET['p'], hex2bin($meta['salt']), 100000, 32);
$iv = hex2bin($meta['iv']);
$decrypted = openssl_decrypt(file_get_contents($encPath), 'AES-256-CBC', $key, 0, $iv);

// 强制下载(防止 XSS & MIME sniffing)
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . rawurlencode($meta['original_name']) . '"');
header('Content-Length: ' . strlen($decrypted));
header('X-Content-Type-Options: nosniff');
echo $decrypted;
exit;
?>

安全增强建议

  • ✅ 使用 HTTPS 部署,杜绝明文传输密码与密文
  • ✅ 将 uploads/ 目录置于 Web 根目录外,或通过 .htaccess 禁止直接访问
  • ✅ 增加文件大小限制、MIME 白名单校验(finfo_file()
  • ✅ 生产环境使用独立密钥管理服务(如 HashiCorp Vault),而非硬编码或 URL 参数传密钥
⚠️ 注意:本文示例为简化教学版。实际项目中请严格校验输入、记录操作日志、启用 PHP OpenSSL 扩展,并定期审计加密流程。

通过以上实现,你已构建起端到端可控的文件加密通道——既满足合规要求,又无需引入复杂框架。安全不是功能,而是贯穿每一行代码的习惯。

```