本文目录导读:

在 PHP 开发中,客户端加密通常指的是浏览器端(JavaScript)加密,因为 PHP 本身是服务端语言,不能直接在客户端运行,PHP 可以配合 JavaScript 实现完整的加密方案。
客户端加密方案(JavaScript)
Web Crypto API(推荐)
现代浏览器内置的加密标准,无需额外库。
// 生成密钥
const key = await crypto.subtle.generateKey(
{ name: 'AES-GCM', length: 256 },
true,
['encrypt', 'decrypt']
);
// 加密数据
async function encryptData(data, key) {
const encoder = new TextEncoder();
const dataBuffer = encoder.encode(data);
const iv = crypto.getRandomValues(new Uint8Array(12));
const encrypted = await crypto.subtle.encrypt(
{ name: 'AES-GCM', iv: iv },
key,
dataBuffer
);
return {
encrypted: new Uint8Array(encrypted),
iv: iv
};
}
// 使用
const result = await encryptData('要加密的数据', key);
CryptoJS(第三方库)
更简单,兼容老浏览器。
// 引入 CryptoJS
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
// AES 加密
const key = CryptoJS.enc.Utf8.parse('your-secret-key-32bytes');
const iv = CryptoJS.lib.WordArray.random(16);
function encryptData(data) {
const encrypted = CryptoJS.AES.encrypt(data, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return {
ciphertext: encrypted.toString(),
iv: CryptoJS.enc.Hex.stringify(iv)
};
}
PHP 服务端解密
<?php
// 使用 OpenSSL 解密(对应 Web Crypto API)
function decryptClientData($encryptedBase64, $ivBase64, $key) {
$encrypted = base64_decode($encryptedBase64);
$iv = base64_decode($ivBase64);
$decrypted = openssl_decrypt(
$encrypted,
'AES-256-GCM',
$key,
OPENSSL_RAW_DATA,
$iv,
$tag // 如果需要认证标签
);
return $decrypted;
}
// 对应 CryptoJS 的 AES-CBC 解密
function decryptCryptoJSData($ciphertext, $ivHex, $key) {
$iv = hex2bin($ivHex);
$encrypted = base64_decode($ciphertext);
return openssl_decrypt(
$encrypted,
'AES-256-CBC',
$key,
OPENSSL_RAW_DATA,
$iv
);
}
实际的常见场景
密码传输加密(HTTPS 之外的额外保护)
// 前端
// 获取 RSA 公钥
const publicKey = await fetch('/api/public-key').then(r => r.json());
async function encryptPassword(password) {
const keyData = await importPublicKey(publicKey);
const encrypted = await crypto.subtle.encrypt(
{
name: 'RSA-OAEP',
algorithm: { name: 'RSA-OAEP', hash: 'SHA-256' }
},
keyData,
new TextEncoder().encode(password)
);
return btoa(String.fromCharCode(...new Uint8Array(encrypted)));
}
// PHP 服务端
$encryptedPassword = $_POST['encrypted_password'];
$privateKey = openssl_pkey_get_private(file_get_contents('private.pem'));
openssl_private_decrypt(
base64_decode($encryptedPassword),
$decrypted,
$privateKey,
OPENSSL_PKCS1_OAEP_PADDING
);
防篡改请求(HMAC 签名)
// 前端生成签名
async function generateSignature(data, secretKey) {
const encoder = new TextEncoder();
const dataBuffer = encoder.encode(JSON.stringify(data));
const key = await crypto.subtle.importKey(
'raw',
encoder.encode(secretKey),
{ name: 'HMAC', hash: 'SHA-256' },
false,
['sign']
);
const signature = await crypto.subtle.sign('HMAC', key, dataBuffer);
return btoa(String.fromCharCode(...new Uint8Array(signature)));
}
// 发送请求时携带签名
fetch('/api/secure', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Signature': signature
},
body: JSON.stringify(data)
});
// PHP 验证签名
$signature = $_SERVER['HTTP_X_SIGNATURE'];
$data = file_get_contents('php://input');
$secretKey = 'your-secret-key';
$expectedSignature = base64_encode(
hash_hmac('sha256', $data, $secretKey, true)
);
if (hash_equals($expectedSignature, $signature)) {
// 签名有效
}
重要注意事项
⚠️ 安全警告:
-
客户端加密不等于安全
- 所有密钥和逻辑都暴露在浏览器中
- 用户可以看到和修改代码
-
必须使用 HTTPS
- 客户端加密是额外保护,不能替代 HTTPS
- HTTPS 提供传输层加密
-
密钥管理
- 永远不要在客户端密钥中写死密钥
- 敏感密钥必须放在服务端
-
适合的场景
- 短期敏感数据(如密码)的临时保护
- 防止服务器日志记录明文数据
- 数据完整性验证(HMAC)
完整示例:密码加密传输
// 前端 (encrypt.js)
async function submitWithEncryption() {
const password = document.getElementById('password').value;
// 获取服务器公钥
const response = await fetch('/api/get-rsa-key');
const { publicKey } = await response.json();
// 导入公钥
const key = await crypto.subtle.importKey(
'spki',
base64ToArrayBuffer(publicKey),
{
name: 'RSA-OAEP',
hash: 'SHA-256'
},
false,
['encrypt']
);
// 加密密码
const encrypted = await crypto.subtle.encrypt(
{ name: 'RSA-OAEP' },
key,
new TextEncoder().encode(password)
);
// 提交加密数据
const formData = new FormData();
formData.append('encrypted_password', arrayBufferToBase64(encrypted));
fetch('/api/login', {
method: 'POST',
body: formData
});
}
// PHP 后端 (login.php)
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$encryptedPassword = base64_decode($_POST['encrypted_password']);
// 私钥解密
$privateKey = openssl_pkey_get_private(file_get_contents('rsa_private.pem'));
openssl_private_decrypt(
$encryptedPassword,
$decryptedPassword,
$privateKey,
OPENSSL_PKCS1_OAEP_PADDING
);
// 验证密码
if (password_verify($decryptedPassword, $user['password_hash'])) {
// 登录成功
}
}
建议组合使用:
- HTTPS(传输层加密)
- 客户端加密(敏感数据额外保护)
- 服务端验证(如 HMAC 签名)
- 安全令牌(防 CSRF)
客户端加密主要用于增加一层防护,不能作为唯一的安全措施,核心安全还是依赖服务端验证。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播