微信小程序登录授权、获取用户敏感信息、解密手机号,javax.crypto.IllegalBlockSizeException: last block incomplete in decryption

    //小程序的key和秘钥
    private final String wechatAppId = "";
    private final String wechatSecretKey = " ";
    private final String grantType = "authorization_code";
    //根据微信登录返回的code获取解密的key的接口
    private final String wxhttpurl = "https://api.weixin.qq.com/sns/jscode2session";

//   //根据微信登录返回的code获取openId和sessionkey

    @RequestMapping(value = "getCode.do", method = RequestMethod.POST)
    public Map getCode(String code){
        Map map = new HashMap();
        if (code == null || code.length() == 0) {
            map.put("status", 0);
            map.put("msg", "code 不能为空");
            return map;
        }
        String params = "appid=" + wechatAppId + "&secret=" + wechatSecretKey + "&js_code=" + code + "&grant_type=" + grantType;
        String sr = HttpRequest.sendGet(wxhttpurl, params);
        JSONObject jsonObject = (JSONObject)JSONObject.parse(sr);
        if(!sr.contains("session_key")||!sr.contains("openid")){
            log.error(sr);
            map.put("status", jsonObject.get("errcode"));
            map.put("msg", jsonObject.get("errmsg"));
            return map;
        }
        String sessionKey = jsonObject.get("session_key").toString();
        String openId = jsonObject.get("openid").toString();
        //客户身份信息解密需要,考虑安全缓存在服务端
        stringRedisTemplate.opsForValue().set("sessionKey_"+openId,sessionKey,1000*60*5);
        map.put("200","OK");
        map.put("openId",openId);
        return map;
    }

解密工具类:

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

            // 如果密钥不足16位,那么就补足.  这个if 中的内容很重要
            int base = 16;
            keyByte = completToBase(keyByte,base);
            ivByte = completToBase(ivByte,base);
            // 初始化
            Security.addProvider(new BouncyCastleProvider());
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
            SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
            AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
            parameters.init(new IvParameterSpec(ivByte));
            cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化
            byte[] resultByte = cipher.doFinal(dataByte);
            if (null != resultByte && resultByte.length > 0) {
                String result = new String(resultByte, "UTF-8");
                return JSONObject.parseObject(result);
            }
        return null;
    }

    //补全数组位数
    public static byte[] completToBase(byte[] bytes,int base){
        byte[] temp = new byte[]{};
        if (bytes.length % base != 0) {
            int groups = bytes.length / base + (bytes.length % base != 0 ? 1 : 0);
            temp = new byte[groups * base];
            Arrays.fill(temp, (byte) 0);
            System.arraycopy(bytes, 0, temp, 0, bytes.length);
        }
        return temp;
    }

 前端调用登录接口的时候一直报错javax.crypto.IllegalBlockSizeException: last block incomplete in decryption,很纳闷看了半天,也没整理出来,后来发现,原来是前端传参通过url的方式,参数中包含很多的特殊字符,后端接收到的参数已经变了。

后来前端改成formdata方式传参就ok了

 

你可能感兴趣的:(JavaSE,JavaScript)