收藏
回答

激励广告回调无法按步骤算出signature

框架类型 问题类型 API/组件名称 终端类型 微信版本 基础库版本
小游戏 需求 激励广告服务器回调 微信安卓客户端

回调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&timestamp=1766556086388

按文档描述,尝试了各种方式,都无法算出signature;尝试解密也失败

能否提供示例代码?

回答关注问题邀请回答
收藏

7 个回答

  • 书
    01-06

    要不是看了下面那段示例的java代码,只看文档完全想不到, 包括decodeURIComponent,sha256 拼接字符串的编码 ,全都不能使用默认的utf8,都要手动改成ISO_8859_1 (latin1)

    01-06
    有用 1
    回复
  • 啊喂
    啊喂
    2025-12-30
    // 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);
    }
    
    2025-12-30
    有用 1
    回复 1
    • 西风
      西风
      03-25
      按照这个方式,解密可以了,但是校验签名还有问题,能发下校验签名的代码吗?
      03-25
      回复
  • 大胡子
    大胡子
    01-21

    5%的验签失败率,求救

    01-21
    有用
    回复
  • 黄小衔
    黄小衔
    01-06

    解密到时解出来了,签名过不去。字节流签名到时第一次见

    01-06
    有用
    回复
  • 永恒
    永恒
    2025-12-26

    我的原始内容 encrypt 还带 ?? 这种东西,我是真不知道怎么拼接这个东西。node 服务,验签一直通不过。想要本地自己测试都不行,复制出来的 entrypt 根本用不了。是要先 解码 entrypt 在参与验签吗?

    2025-12-26
    有用
    回复 2
    • 永恒
      永恒
      2025-12-26
      对 encrypt 解码也会报错。
      2025-12-26
      回复
    • 应如是
      应如是
      2025-12-26
      完全不知道,几乎每个解码/编码格式都蒙了一遍,拼不出来,只能等官方发示例代码
      2025-12-26
      回复
  • 应如是
    应如是
    2025-12-24

    拼接的时候,encrypt应该是个什么形式?没有encrypt时校验可以通过,正确计算出signature;但是加上了encrypt就无法计算出来,能不能给一下示例代码?

    2025-12-24
    有用
    回复
  • 智能回答 智能回答 本次回答由AI生成
    2025-12-24
    有用
    回复
登录 后发表内容