WeChat applet decrypts encryptedData error: pad block corrupted solution

I encountered a pad block corrupted error today, and found out from the code that it was an error caused by doFinal() in Cipher .

code:

public static JSONObject getUserInfo(String encryptedData, String sessionKey, String iv) {
    try {
      // 加密秘钥
      byte[] keyByte = Base64.decodeBase64(sessionKey);
      // 偏移量
      byte[] ivByte = Base64.decodeBase64(iv);

      // 如果密钥不足16位,那么就补足.  这个if 中的内容很重要
      int base = 16;
      if (keyByte.length % base != 0) {
        int groups = keyByte.length / base + 1;
        byte[] temp = new byte[groups * base];
        Arrays.fill(temp, (byte) 0);
        System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
        keyByte = temp;
      }
      // 初始化
      Security.addProvider(new BouncyCastleProvider());
      Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
      SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
      AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
      parameters.init(new IvParameterSpec(ivByte));
      cipher.init(Cipher.DECRYPT_MODE, spec, parameters); // 初始化
      // 被加密的数据
      byte[] dataByte = Base64.decodeBase64(encryptedData);
      byte[] resultByte = cipher.doFinal(dataByte);
      if (null != resultByte && resultByte.length > 0) {
        String result = new String(resultByte, StandardCharsets.UTF_8);
        log.info("解析微信加密数据==>{}", result);
        return JSONObject.parseObject(result);
      }
    } catch (BadPaddingException e) {
      log.error("解析微信加密数据失败", e);
      throw Exceptions.fail(WECHAT_SESSION_EXPIRED);
    }
    return null;
  }

mistake:

javax.crypto.BadPaddingException: pad block corrupted
	at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher$BufferedGenericBlockCipher.doFinal(Unknown Source)
	at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineDoFinal(Unknown Source)
	at javax.crypto.Cipher.doFinal(Cipher.java:2087)
	at com.saic.ebiz.service.util.AESUtils.getUserInfo(AESUtils.java:62)
	at com.saic.ebiz.service.util.AESUtils.main(AESUtils.java:86)
Exception in thread "main" java.lang.NullPointerException
	at com.saic.ebiz.service.util.AESUtils.main(AESUtils.java:87)

After finding the official WeChat community, I found out that this is a bug of WeChat. It is not clear whether there is a solution now, but we can solve it ourselves.

Reason: wx.login obtains session_key, and sessionKey is the key to decrypt encryptedData, so once our wx.login is obtained after wx.getUserInfo(getphonenumber…), the sessionKey we store is definitely not the key to obtain encryptedData currently.

My solution:

In the first method, the front end ensures that the code obtained by wx.login is before the getUserInfo(getphonenumber…) operation.

The second method can also be the backend. The community also provides another solution Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC"); remove BC, I haven't tried it yet, because I Solved it with the previous method.

Guess you like

Origin blog.csdn.net/zlfjavahome/article/details/129919437