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

JWE负载解密失败:AES/GCM/NoPadding标签不匹配问题求助

AES/GCM解密出现Tag mismatch问题求助

我尝试对负载(payload)进行签名并加密,但对方解密数据时返回以下错误:

AES/GCM/NoPadding decryption failed: Tag mismatch!

我使用的是3.3版本的web-token JWT框架,相关代码如下:

public static function encryptPayload($payload)
{
    $payload = json_encode($payload);
    $selfPrivateKey = self::getSelfPrivateKey();
    $publicKey = self::getPublicKey();

    //  -----   Build JWS Object    -----   Begin   -----
    // Init JWS algorithm
    $jwsAlgorithmManager = new AlgorithmManager([new RS256()]);
    // Build JWS object and sign the message by merchant's private key
    $jwsBuilder = new JWSBuilder($jwsAlgorithmManager);
    $jws = $jwsBuilder
        ->create()
        ->withPayload($payload)
        ->addSignature($selfPrivateKey, [
            'alg' => 'RS256',
            'kid' => 0002,
        ])
        ->build();
    $jwsSerializer = new JwsCompactSerializer();
    $jwsString = $jwsSerializer->serialize($jws, 0);
    //  -----   Build JWS Object    -----    END    -----

    //  -----   Build JWE Object    -----   Begin   -----
    // Init JWE algorithm
    $jweKeyEncryptionAlgorithmManager = new AlgorithmManager([
        new RSAOAEP256(),
    ]);
    // Init JWE encryption algorithm
    $jweContentEncryptionAlgorithmManager = new AlgorithmManager([
        new A128GCM(),
    ]);
    $compressionMethodManager = new CompressionMethodManager([
        new Deflate(),
    ]);
    // Build JWE object and encrypt the message by public key
    $jweBuilder = new JWEBuilder(
        $jweKeyEncryptionAlgorithmManager,
        $jweContentEncryptionAlgorithmManager,
        $compressionMethodManager
    );
    $jwe = $jweBuilder
        ->create()
        ->withPayload($jwsString)
        ->withSharedProtectedHeader([
            'alg' => 'RSA-OAEP-256',
            'enc' => 'A128GCM',
            'kid' => '0005',
        ])
        ->addRecipient($publicKey)
        ->build();

    $jweSerializer = new JweCompactSerializer();
    $jweString = $jweSerializer->serialize($jwe, 0);
    //  -----   Build JWE Object    -----    END    -----
    // $this->logger->info("Encrypted String: $jweString");
    return $jweString;
}

可能的排查方向

  • 压缩方法不兼容:你加密时启用了Deflate压缩,需确认对方解密时是否同样启用了该压缩支持,且压缩/解压参数一致。可以先移除压缩逻辑(注释掉$compressionMethodManager相关代码,JWEBuilder不传入压缩管理器),测试是否解决问题。
  • 密钥配对错误:确认对方使用的私钥是否与你加密用的公钥(kid=0005)完全配对。密钥不匹配会导致对称密钥解密错误,进而触发GCM标签验证失败。
  • JWS内容被修改:检查$jwsString在传入JWE前是否被意外编码、转义或截断。可以自行打印该字符串,然后模拟解密JWE,验证得到的JWS是否能正常验签。
  • JWE序列化格式不一致:你使用的是Compact序列化格式,需确认对方是否用相同的格式解析JWE,不同序列化格式会导致数据结构错误。
  • 框架版本兼容性:核对对方使用的web-token框架版本,不同版本可能存在算法实现细节差异,比如RSA-OAEP-256的哈希算法是否统一为SHA-256。
  • kid格式不统一:JWS中的kid是数字0002,JWE中的kid是字符串'0005',确认对方是否能正确识别两种格式的kid,避免因密钥选择错误导致解密失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 13:27:09