收藏
回答

小程序一键授权手机号后端解密失败?

您好,我们用的小程序一键授权的方案,需要获取手机号,这个接口偶尔报错,一天差不多3到4个,但是我们前端的基础库的版本是 2.16.1,前端代码是这样 :

<button

id="pageReserveBtnbtn-area"

open-type="getPhoneNumber"

bindgetphonenumber="handleGetPhoneNumber";

我的后端代码是:public Map<String, Object> getWeChatPhoneNumber(Map<String, Object> params) {
    try {
        WechatLoginReqDTO dto = new WechatLoginReqDTO();
        dto.setCode(String.valueOf(params.get("code")));
        OauthRespDTO oauthRespDTO = wechatOauthRestService.wechatAppletLogin(dto);
        log.info("---- getWeChatPhoneNumber oauthRespDTO: {}", WkUtils.objectToJson(oauthRespDTO));
        String str = WeChatUtil.decryptData(String.valueOf(params.get("encryptedData")), oauthRespDTO.getSessionKey(), String.valueOf(params.get("iv")));
        return new Gson().fromJson(str, Map.class);
    } catch (Exception e) {
        log.error("---- getWeChatPhoneNumber error ----:{}", e.getMessage(), e);
        throw new ApiClientException("wechat.auth.connection.failed");
    }
}
private static byte[] decrypt(byte[] content, byte[] key, byte[] iv) throws Exception {
    Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
    Key keySpec = new SecretKeySpec(key, KEY_ALGORITHM);
    cipher.init(Cipher.DECRYPT_MODE, keySpec, generateIV(iv));
    return cipher.doFinal(content);
}



public static String decryptData(String encryptedData, String session_key, String ivStr) throws Exception {
    log.info("encryptedData: {}", encryptedData);
    log.info("sessionKey: {}", session_key);
    log.info("iv: {}", ivStr);
    Base64.Decoder decoder = Base64.getDecoder();
    byte[] content = decoder.decode(encryptedData);
    byte[] key = decoder.decode(session_key);
    if (key.length != 16) {
        log.error("SessionKey解码后长度异常: {}", key.length);
        throw new IllegalArgumentException("Invalid sessionKey");
    }
    byte[] iv = decoder.decode(ivStr);
    if (iv.length != 16) {
        throw new IllegalArgumentException("Invalid iv length: " + iv.length);
    }
    try {
        byte[] plain = decrypt(content, key, iv);
        return new String(plain, StandardCharsets.UTF_8);
    } catch (IllegalArgumentException e) {
        log.error("参数长度异常:{} ", e.getMessage(), e);
        throw new RuntimeException("解密参数错误");
    } catch (InvalidKeyException e) {
        log.error("无效密钥: {}", e.getMessage(), e);
        throw new RuntimeException("SessionKey无效");
    } catch (BadPaddingException e) {
        log.error("填充错误,请检查参数完整性:{} ", e.getMessage(), e);
        throw new RuntimeException("数据损坏");
    } catch (Exception e) {
        log.error("解密未知错误: {}", e.getMessage(), e);
        throw new RuntimeException("解密失败");
    }
}


解密算法是:private static final String KEY_ALGORITHM = "AES";
private static final String DEFAULT_CIPHER_ALGORITHM = "AES/CBC/PKCS7Padding";


现在log日志报错是:log.error("填充错误,请检查参数完整性:{} ", e.getMessage(), e);
throw new RuntimeException("数据损坏");


回答关注问题邀请回答
收藏
登录 后发表内容