为什么我的Java Base64解码每次运行得到的结果都不一致?
问题根本原因
你当前的错误完全是Base64编码/解码逻辑搞反导致的概率性异常:
GCP KMS的AsymmetricSignResponse.getSignature()返回的ByteString存储的是签名后的原始二进制数据,并非Base64编码后的可打印字符串。你直接把随机的二进制字节流喂给Base64解码器,只有当二进制内容刚好全部符合Base64字符集规则、且字节长度符合4字节对齐要求时,才会侥幸解码成功,其余场景都会抛出"Last unit does not have enough valid bits"错误,这就是你遇到的结果不稳定的核心原因。
你需要把原始二进制签名做Base64编码后才能放到PEM格式的证书请求里,和你现在的操作完全相反。
排查步骤
- 验证返回值属性
在getSignature().toByteArray()之后新增日志:
- 打印字节数组的长度,确认非对称签名的长度和你使用的密钥算法匹配(比如2048位RSA签名长度为256字节)
- 把字节数组直接转成UTF-8字符串打印,会看到大量不可打印的乱码,即可确认返回内容不是Base64编码的字符串
- 修正业务逻辑
你当前的代码逻辑完全颠倒,修改参考如下:
public enum GoogleCertificateProvider { ... // 直接获取原始二进制签名,适用于后续二进制处理场景 public byte[] getRawSignature(Digest digest) { AsymmetricSignResponse result = client.asymmetricSign(keyVersionName, digest); return result.getSignature().toByteArray(); } // 生成PEM格式需要的Base64编码签名,自动按64字符换行符合规范 public String getPemFormatSignature(Digest digest) { byte[] rawSignature = getRawSignature(digest); return Base64.getMimeEncoder(64, new byte[]{'\n'}).encodeToString(rawSignature); } ... }
- 稳定性验证
连续调用签名接口100次以上,确认不会再抛出解码错误,再用openssl命令校验生成的CSR文件是否可正常解析。
内容的提问来源于stack exchange,提问作者gear4
相关产品推荐
相关产品推荐

