Google Pay直连集成:如何正确生成符合要求的加密密钥?
我正在用Direct Integration方式把Google Pay集成到Android应用里,在Google Pay & Wallet Console提交应用进入生产模式前,必须在「加密密钥」板块上传至少一个加密密钥,但我不知道怎么正确获取或生成这个密钥。
已尝试的操作
1. OpenSSL操作
- 用
prime256v1曲线生成公私钥 - 执行以下命令提取公钥并验证是否以
0x04(非压缩格式)开头:
openssl ecparam -genkey -name prime256v1 -noout -out private_key.pem
openssl ec -in private_key.pem -pubout -out public_key.pem
openssl ec -pubin -in public_key.pem -text -noout
- 提取二进制非压缩公钥: ```bash openssl ec -pubin -in public_key.pem -outform DER | tail -c +28 > uncompressed_key.bin
- 转换为Base64格式:
openssl base64 -in uncompressed_key.bin -out uncompressed_key_base64.txt
> 结果:密钥被Google Pay控制台拒绝,错误提示「公钥的第一个字节必须为0x04(非压缩点格式)」 ### 2. 跨环境测试 - 在Windows PowerShell和Ubuntu的OpenSSL中执行相同步骤,遇到同样问题 - 检查解码后的二进制文件,确认符合ECC P-256非压缩规范,但仍被拒绝 ### 3. JKS相关尝试 - 曾怀疑密钥是否和Android应用签名用的JKS文件(密钥别名及密码)有关,但和官方文档不符 ## 疑问 - 如何正确生成符合要求的加密密钥? - 用什么工具或流程能确保和Google Pay兼容? - 有没有开发者验证过的标准文档或工具可以参考? --- # 解决方案 ### 一、正确的密钥生成步骤(修正版) 你的OpenSSL流程核心方向是对的,但提取二进制公钥时可能因系统工具差异出现偏差,试试这个更严谨的流程: 1. 生成ECC P-256私钥: ```bash openssl ecparam -genkey -name prime256v1 -noout -out ec_private.pem
- 强制导出非压缩格式公钥:
openssl ec -in ec_private.pem -pubout -outform PEM -out ec_public.pem -conv_form uncompressed
3. 验证公钥格式: 执行以下命令,输出的公钥开头必须是`04`: ```bash openssl ec -pubin -in ec_public.pem -text -noout
正确输出示例:
Public-Key: (256 bit) pub: 04:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx: xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx: xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx: xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx ASN1 OID: prime256v1 NIST CURVE: P-256
- 提取二进制公钥并转无换行Base64:
openssl ec -pubin -in ec_public.pem -outform DER | dd bs=1 skip=27 > raw_public.bin
openssl base64 -in raw_public.bin | tr -d '\n' > public_key.base64
### 二、关键注意事项 - **强制指定非压缩格式**:默认情况下OpenSSL可能导出压缩格式公钥,必须加`-conv_form uncompressed`参数 - **Base64不能有换行**:Google Pay控制台要求上传的Base64字符串是连续无换行的,用`tr -d '\n'`彻底清除换行符 - **密钥用途独立**:这个加密密钥和应用签名的JKS完全无关,是单独用于Google Pay交易数据加密的ECC密钥 ### 三、替代工具(避免命令行踩坑) 如果还是遇到问题,可尝试以下两种更可靠的方式: #### 1. Java keytool方式 ```bash # 生成ECC密钥库 keytool -genkeypair -alias gpay-encryption -keyalg EC -keysize 256 -keystore gpay-keys.jks -storepass your-password -keypass your-password -dname "CN=Google Pay Encryption" # 导出公钥到PEM文件 keytool -exportcert -alias gpay-encryption -keystore gpay-keys.jks -rfc -file ec_public.pem # 后续提取二进制和转Base64步骤和上面一致
2. Android代码生成(Kotlin)
直接在项目里生成符合要求的公钥,避免命令行工具的系统差异:
import java.security.KeyPairGenerator import java.security.spec.ECGenParameterSpec import android.util.Base64 fun generateGooglePayEncryptionKey(): String { val keyGen = KeyPairGenerator.getInstance("EC") keyGen.initialize(ECGenParameterSpec("secp256r1")) // secp256r1与prime256v1等价 val keyPair = keyGen.generateKeyPair() val publicKeyBytes = keyPair.public.encoded // 跳过ASN.1头(前27字节),取后续65字节的非压缩公钥内容 val rawPublicKey = publicKeyBytes.copyOfRange(27, publicKeyBytes.size) // 生成无换行的Base64字符串 return Base64.encodeToString(rawPublicKey, Base64.NO_WRAP) }
运行后直接复制输出的字符串到Google Pay控制台即可。
内容的提问来源于stack exchange,提问作者Robert Green MBA

