ColdFusion调用Amazon Pay API报InvalidRequestSignature错误求解
核心问题定位
你遇到的错误核心是签名填充方式不匹配,你参考的普通RSA签名教程使用的是PKCS#1 v1.5填充,而Amazon Pay要求的签名算法是RSASSA-PSS(带概率签名方案的RSA签名),这是两种完全不同的签名实现,哪怕待签字符串完全一致,生成的签名也会不匹配。
另外你提供的报错信息里,Amazon服务端收到的待签字符串哈希和你本地生成的不一致,还要额外排查换行符的问题。
具体排查&修复步骤
- 修复签名算法实现
ColdFusion 2016内置的sign()函数默认仅支持PKCS#1 v1.5填充的RSA签名,无法直接生成RSASSA-PSS格式的签名,你需要调用Java安全API实现,示例代码如下:
<cffunction name="generateAmazonPaySignature" access="private" returnType="string"> <cfargument name="stringToSign" type="string" required="true"> <cfargument name="privateKeyStr" type="string" required="true"> <!--- 这里privateKeyStr是去除了首尾PEM标记和换行的私钥内容 ---> <cfscript> // 解码Base64格式的私钥 var decodedKey = binaryDecode(arguments.privateKeyStr, "base64"); var keySpec = createObject("java", "java.security.spec.PKCS8EncodedKeySpec").init(decodedKey); var keyFactory = createObject("java", "java.security.KeyFactory").getInstance("RSA"); var privateKey = keyFactory.generatePrivate(keySpec); // 配置RSASSA-PSS参数:SHA256哈希,MGF1掩码,盐长等于哈希长度(32字节) var mgfParam = createObject("java", "java.security.spec.MGF1ParameterSpec").SHA256; var pssParam = createObject("java", "java.security.spec.RSAPSSParameterSpec").init("SHA-256", "MGF1", mgfParam, 32, 1); var signatureObj = createObject("java", "java.security.Signature").getInstance("RSASSA-PSS"); // 生成签名 signatureObj.initSign(privateKey); signatureObj.setParameter(pssParam); signatureObj.update(arguments.stringToSign.getBytes("UTF-8")); var signBytes = signatureObj.sign(); // 返回Base64编码的签名 return binaryEncode(signBytes, "base64"); </cfscript> </cffunction>
如果运行时提示类不存在,可将最新版本的BouncyCastle安全库jar包放入ColdFusion的cfusion/lib目录,重启服务后再测试。
验证换行符一致性
你代码中使用Chr(10)作为换行符是正确的,但要确保所有拼接的字符串没有混入Chr(13)(Windows换行符),可以将生成的待签字符串转换为二进制查看字节,确认换行位置的字节是0A而非0D0A。校验哈希一致性
将你ColdFusion生成的规范请求字符串、待签字符串分别做SHA256哈希,和Node SDK生成的对应哈希做对比,确认完全一致,避免肉眼对比时看不到不可见字符的问题。
内容的提问来源于stack exchange,提问作者Vicky
相关产品推荐
相关产品推荐

