PHP项目怎样隐藏敏感配置信息

wen PHP项目 32

本文目录导读:

PHP项目怎样隐藏敏感配置信息

  1. 使用环境变量(最推荐)
  2. 配置文件分离与权限控制
  3. 使用密钥管理服务
  4. 混淆与加密(防御性做法,非替代方案)
  5. 平台特定的配置方式
  6. 关键提示

在PHP项目中隐藏敏感配置信息(如数据库密码、API密钥、加密盐值等)是保障安全的核心实践,以下是几种主流且推荐的方法,按推荐程度排序:

使用环境变量(最推荐)

原理

将配置信息存储在服务器环境变量中,而非代码文件里。

实现方式

设置环境变量:

# Linux/Mac 临时设置
export DB_PASSWORD="your_secure_password"
export API_KEY="sk-xxx"
# 永久设置(在 ~/.bashrc 或 /etc/environment)
echo 'export DB_PASSWORD="your_secure_password"' >> ~/.bashrc
source ~/.bashrc

PHP 读取环境变量:

// config.php
define('DB_HOST', getenv('DB_HOST') ?: 'localhost');
define('DB_NAME', getenv('DB_NAME') ?: 'mydb');
define('DB_USER', getenv('DB_USER') ?: 'root');
define('DB_PASS', getenv('DB_PASS') ?: '');
define('API_KEY', getenv('API_KEY'));
// 使用
$pdo = new PDO(
    "mysql:host=" . DB_HOST . ";dbname=" . DB_NAME,
    DB_USER,
    DB_PASS
);

使用 Dotenv 库(.env 文件):

composer require vlucas/phpdotenv
// .env 文件(切勿提交到 Git)
DB_HOST=localhost
DB_NAME=mydb
DB_USER=root
DB_PASS=s3cr3t
API_KEY=sk-xxxxxxxx
// index.php
require_once __DIR__ . '/vendor/autoload.php';
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();
define('DB_PASS', $_ENV['DB_PASS']);

重要:.env 添加到 .gitignore

.env
.env.local
.env.*.local

配置文件分离与权限控制

结构

project/
├── config/
│   ├── config.php          # 公共配置
│   └── config.local.php    # 敏感配置(被 .gitignore)
├── .gitignore
└── index.php

config.php:

// 公共配置,可提交
define('SITE_NAME', 'My App');
define('DEBUG', false);
// 加载本地配置
if (file_exists(__DIR__ . '/config.local.php')) {
    require_once __DIR__ . '/config.local.php';
}

config.local.php:

// 敏感配置,不提交
define('DB_PASS', 's3cr3t');
define('API_KEY', 'sk-xxx');

.gitignore:

config.local.php
*.local.php

文件权限设置:

# 禁止其他用户读取
chmod 640 config.local.php
# 或更严格
chmod 600 config.local.php

使用密钥管理服务

适合微服务或云环境:

AWS Secrets Manager

use Aws\SecretsManager\SecretsManagerClient;
use Aws\Exception\AwsException;
$client = new SecretsManagerClient([
    'version' => 'latest',
    'region'  => 'us-east-1'
]);
try {
    $result = $client->getSecretValue([
        'SecretId' => 'prod/db/password'
    ]);
    $secret = json_decode($result['SecretString'], true);
    define('DB_PASS', $secret['password']);
} catch (AwsException $e) {
    error_log("Failed to retrieve secret: " . $e->getMessage());
    exit(1);
}

HashiCorp Vault

$vault = new VaultClient([
    'base_uri' => 'https://vault.example.com',
    'token'    => getenv('VAULT_TOKEN')
]);
$secret = $vault->getSecret('secret/data/db');
define('DB_PASS', $secret['data']['data']['password']);

混淆与加密(防御性做法,非替代方案)

简单的混淆

// 不推荐!只是增加难度
define('DB_PASS', base64_decode('czNjcjN0'));

使用加密配置文件

// 加密文件(使用 openssl)
// openssl enc -aes-256-cbc -salt -in config.plain -out config.enc -k YourKey
function decryptConfig($encryptedFile, $key) {
    $data = file_get_contents($encryptedFile);
    $cipher = "aes-256-cbc";
    $ivlen = openssl_cipher_iv_length($cipher);
    $iv = substr($data, 0, $ivlen);
    $encrypted = substr($data, $ivlen);
    return openssl_decrypt($encrypted, $cipher, $key, OPENSSL_RAW_DATA, $iv);
}
$config = json_decode(decryptConfig('config.enc', getenv('CONFIG_KEY')), true);
define('DB_PASS', $config['db_password']);

平台特定的配置方式

Docker 环境

# docker-compose.yml
services:
  app:
    environment:
      - DB_PASSWORD=${DB_PASSWORD}
      - API_KEY=${API_KEY}
    env_file:
      - .env

Kubernetes Secrets

apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
data:
  password: czNjcjN0   # base64 encoded

云平台环境变量

  • AWS Elastic Beanstalk: 通过 AWS 控制台设置
  • Heroku: heroku config:set DB_PASSWORD=xxx
  • Azure: 应用设置
做法 推荐度 说明
环境变量 + .env 本地开发最佳,配合 .gitignore
密钥管理服务 生产环境,企业级
配置文件分离 简单项目,配合权限控制
配置文件加密 额外保护,非主要方案
代码中硬编码 绝对禁止

关键提示

  1. 永远不要将敏感信息提交到版本控制(Git)
  2. 永远不要在代码中硬编码密钥
  3. 使用 .gitignore 排除所有敏感文件
  4. 为不同环境(开发/测试/生产)使用不同的配置
  5. 定期轮换密钥和密码
  6. 记录敏感信息访问日志
  7. 遵循最小权限原则

选择哪种方法取决于你的项目规模、部署方式和安全需求,对于大多数 PHP 项目,环境变量 + .env 文件 是最平衡的解决方案。

抱歉,评论功能暂时关闭!