回调url的原始内容为/platform/wechat/verifyAd?encrypt=e*%A4%09%19%AE)%B6P%B2%DE%89%AE%F3I%D1%86%D1J'A%F1%11%A0E%F8%06_%D4%84%9D%D7%AF%EC.%E7%0C%E8%80%EE%B9%BC%FDQy%AC'%5C%85%CE%FF*%0AR%FF%A5%EE%97%5E%B2%B6%9D%C43B%3C5p%D5(8%EA%A6%DD%D2%130R%F7t%80%01%9D%FD%1E1%04%92%E1%23!%5E%E7'%9C%A9N%A6f%25%88J%BE%DD%C2%8A%C6i%8F%10%AE%B1%DD%A4c%DD%03%0C%24GY%E0%8CZ%8B%C2P%1A.%FB(%9D%3B%3C%E8%A1%3C%EB0k%97%0BL%FDR%F3%D2%25B%CF%23%0A%BA%C7%B9%60%3DA%8Dm&nonce=1609138150&signature=bd577bb4fa3e2d40a8251a2fc72d8e195ecd7d2d769a1475d2c91fe0557d3874×tamp=1766556086388
按文档描述,尝试了各种方式,都无法算出signature;尝试解密也失败
能否提供示例代码?

要不是看了下面那段示例的java代码,只看文档完全想不到, 包括decodeURIComponent,sha256 拼接字符串的编码 ,全都不能使用默认的utf8,都要手动改成ISO_8859_1 (latin1)
// java代码测试示例,找了好几个地方,应该是联系到了开发人员,在对方的指导下,通过了验证签名和解密数据 public static void main(String[] args) { try { // 测试参数(替换为实际值) String encryptData = "encrypt值"; String nonce = "nonce值"; String signature = "signature值"; String timestamp = "timestamp值"; String encryptDecoded = URLDecoder.decode(encryptData, StandardCharsets.ISO_8859_1.name()); boolean b = verifySignature(timestamp, nonce, encryptDecoded, signature); System.out.println(b); // 执行解密 String result = decryptEncryptData(encryptData, WX_AD_ENCODING_AES_KEY); System.out.println("解密结果:" + result); } catch (Exception e) { System.err.println("解密失败:" + e.getMessage()); e.printStackTrace(); } } /** * 解密方法(对应PHP的decryptEncryptData函数) * * @param encrypt 加密后的字符串(URL编码格式) * @param encodingAESKey AES密钥(Base64编码格式,末尾会自动补充=) * @return 解密后的明文 * @throws Exception 解密过程中的异常 */ public static String decryptEncryptData(String encrypt, String encodingAESKey) throws Exception { // 1. 处理AES密钥:补充=后Base64解码 String aesKeyWithEqual = encodingAESKey + "="; byte[] aesKey = java.util.Base64.getDecoder().decode(aesKeyWithEqual); // 2. URL解码密文 String encryptDecoded = URLDecoder.decode(encrypt, StandardCharsets.ISO_8859_1.name()); byte[] encryptBytes = encryptDecoded.getBytes(StandardCharsets.ISO_8859_1); // 保持和PHP一致的字节编码 // 3. 验证加密数据长度(至少需要16字节IV) if (encryptBytes.length < 16) { throw new IllegalArgumentException("解密失败: 加密数据长度不足(需要至少16字节IV)"); } // 4. 提取IV(前16字节)和密文(剩余部分) byte[] iv = new byte[16]; System.arraycopy(encryptBytes, 0, iv, 0, 16); byte[] ciphertext = new byte[encryptBytes.length - 16]; System.arraycopy(encryptBytes, 16, ciphertext, 0, ciphertext.length); // 5. 初始化AES解密器(AES-256-CBC,PKCS7填充) Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); // Java中PKCS5Padding等价于PHP的PKCS7Padding SecretKeySpec secretKeySpec = new SecretKeySpec(aesKey, "AES"); IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec); // 6. 执行解密 byte[] decryptedBytes = cipher.doFinal(ciphertext); // 7. 转换为字符串返回(使用UTF-8编码) return new String(decryptedBytes, StandardCharsets.UTF_8); }5%的验签失败率,求救
解密到时解出来了,签名过不去。字节流签名到时第一次见
我的原始内容 encrypt 还带 ?? 这种东西,我是真不知道怎么拼接这个东西。node 服务,验签一直通不过。想要本地自己测试都不行,复制出来的 entrypt 根本用不了。是要先 解码 entrypt 在参与验签吗?
拼接的时候,encrypt应该是个什么形式?没有encrypt时校验可以通过,正确计算出signature;但是加上了encrypt就无法计算出来,能不能给一下示例代码?