You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

phpseclib AES-GCM加密能否与JavaScript WebCrypto兼容互通?

PHP phpseclib 与 WebCrypto AES-GCM 互通问题解决

二者完全兼容,你的问题出在PHP端对密钥和IV的处理上——未正确解码Base64字符串,导致加密使用了错误的密钥/IV字节,最终WebCrypto解密时验证失败抛出OperationError。

问题核心

PHP代码中$TEST_AES_KEY和$TEST_AES_IV是Base64编码字符串,但AES->setKey()和AES->setNonce()需要的是原始字节数据,而非Base64字符串。直接传入Base64会导致实际使用的密钥/IV与WebCrypto端完全不一致,解密自然失败。

修正后的PHP加密代码

<?php
require_once($_SERVER['DOCUMENT_ROOT'] . '/../vendor/autoload.php');
use phpseclib3\Crypt\AES;

$TEST_AES_KEY = "TWw4QCkeZEnXoCDkI1GEHQ==";
$TEST_AES_IV = "CRKTyQoWdWB2n56f";
$message = "123&abc";

$aes = new AES('gcm');
// 关键:对密钥和IV做Base64解码,获取原始字节
$aes->setKey(base64_decode($TEST_AES_KEY));
$aes->setNonce(base64_decode($TEST_AES_IV));

$ciphertext = $aes->encrypt($message);
$tag = $aes->getTag();
// 密文拼接标签后Base64编码的逻辑是正确的
$ciphertextBase64 = base64_encode($ciphertext . $tag);
echo $ciphertextBase64;

验证WebCrypto解密

用修正后的PHP代码生成新的密文,替换前端的messageEncrypted字段,即可正常解密。你的WebCrypto代码逻辑完全正确,无需修改。

互通关键注意事项

  • 密钥/IV字节对齐:确保两端使用的是相同原始字节的密钥和IV,Base64编码仅用于传输存储,使用前必须解码。
  • Tag长度一致:phpseclib默认GCM Tag长度为128位,与WebCrypto指定的tagLength:128匹配,无需额外调整。
  • 数据格式统一:PHP端密文+标签拼接后Base64编码,WebCrypto端解码后直接传入decrypt方法即可,WebCrypto会自动从数据末尾提取16字节(128位)的Tag完成验证。

内容的提问来源于stack exchange,提问作者stk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 16:06:25