Google Pay支付令牌解密时签名验证失败问题求助
Google Pay令牌解密签名验证错误排查
问题概述
尝试使用Python的google-pay-token-decryption包解密Google Pay支付令牌时,持续触发以下签名验证错误:
Could not verify message signatureCould not verify intermediate signing key signature
已尝试将令牌中的\u003d替换为=,但问题未解决;跳过签名验证步骤后可成功解密。同时使用Java的Tink库尝试时,也出现签名验证相关异常。
相关代码与报错信息
Python代码片段
signingKey = [{"keyValue":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIsFro6K+IUxRr4yFTOTO+kFCCEvHo7B9IOMLxah6c977oFzX/beObH4a9OfosMHmft3JJZ6B3xpjIb8kduK4/A==","protocolVersion":"ECv1"},{"keyValue":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEGnJ7Yo1sX9b4kr4Aa5uq58JRQfzD8bIJXw7WXaap/hVE+PnFxvjx4nVxt79SdRuUVeu++HZD0cGAv4IOznc96w==","protocolVersion":"ECv2","keyExpiration":"2154841200000"},{"keyValue":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEGnJ7Yo1sX9b4kr4Aa5uq58JRQfzD8bIJXw7WXaap/hVE+PnFxvjx4nVxt79SdRuUVeu++HZD0cGAv4IOznc96w==","protocolVersion":"ECv2SigningOnly","keyExpiration":"2154841200000"}] recipient_id = "merchant:12345678901234567890" private_key = "string" decryptor = GooglePayTokenDecryptor(signingKey, recipient_id, private_key) decrypted_token = decryptor.decrypt_token(token, False)
Java Tink库报错信息
Exception in thread "main" java.security.GeneralSecurityException: cannot verify signature at com.google.crypto.tink.apps.paymentmethodtoken.PaymentMethodTokenRecipient.verify(PaymentMethodTokenRecipient.java:461) at com.google.crypto.tink.apps.paymentmethodtoken.PaymentMethodTokenRecipient.verifyECV2(PaymentMethodTokenRecipient.java:399) at com.google.crypto.tink.apps.paymentmethodtoken.PaymentMethodTokenRecipient.unsealECV2(PaymentMethodTokenRecipient.java:365) at com.google.crypto.tink.apps.paymentmethodtoken.PaymentMethodTokenRecipient.unseal(PaymentMethodTokenRecipient.java:342) at org.example.AeadExample.main(AeadExample.java:33)
错误含义与解决方法
错误含义
- Could not verify message signature:无法验证支付令牌本身的签名,说明令牌数据可能被篡改,或用于验证的公钥不匹配。
- Could not verify intermediate signing key signature:无法验证谷歌中间签名密钥的签名,意味着你使用的签名密钥不是谷歌官方签发的有效密钥,或是密钥已过期。
解决步骤
确认签名密钥来源有效性:
- 确保
signingKey中的公钥是从谷歌官方获取的最新有效密钥,而非自定义或过期密钥。谷歌会定期更新这些密钥,需从谷歌支付开发者后台同步最新列表。 - 检查
keyExpiration字段,确保当前时间未超过密钥过期时间(示例中2154841200000对应2050年,这个没问题,但需确认实际密钥的有效期)。
- 确保
验证Recipient ID与私钥匹配:
- 确认
recipient_id是谷歌支付控制台中配置的商户ID,格式为merchant:xxxxxx,需与生成支付令牌时使用的ID完全一致。 private_key必须是与谷歌注册的商户公钥对应的私钥,确保私钥未损坏、格式正确(需是PKCS#8格式的PEM字符串,无多余换行或字符)。
- 确认
检查令牌完整性:
- 确保支付令牌在传输过程中未被截断或编码错误,除了替换
\u003d,还要检查是否存在其他转义字符处理不当的情况(比如JSON转义问题)。 - 确认令牌是谷歌支付网关返回的原始完整数据,未经过二次修改。
- 确保支付令牌在传输过程中未被截断或编码错误,除了替换
协议版本兼容性:
- 检查令牌使用的协议版本(ECv1/ECv2)与你传入的
signingKey中的协议版本匹配,确保对应版本的密钥存在且有效。
- 检查令牌使用的协议版本(ECv1/ECv2)与你传入的
Tink库配置检查(Java端):
- 确保Tink库版本是最新稳定版,避免因版本兼容问题导致签名验证失败。
- 确认初始化Tink时已正确加载支付令牌相关的密钥模板,且私钥加载方式正确(需用对应方法解析PKCS#8私钥)。
内容的提问来源于stack exchange,提问作者nartiah
相关产品推荐
相关产品推荐

