Java获取微信用户绑定的手机号

微信官方文档  https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getPhoneNumber.html

全部放在一个Controller里了,方便看。代码中有些是自定义封装的工具类,关键部分就是try代码块中解密的用法。

    @RequestMapping(rootUrl + "decodeWxAppPhone")
    @ResponseBody
    public Object decodeWxAppPhone(HttpServletRequest request,
            HttpServletResponse response) {
        response.setHeader("Access-Control-Allow-Origin", "*");
        ResResult verResult = CommonSignUtils.verifyParamAndPermission(request,
                "encrypted,iv,code");
        if (ObjectHelper.isNotEmpty(verResult.getResObject())) {// 验证未通过
            return verResult.getResObject();
        }
        String encrypted = verResult.getParams().get("encrypted");
        String iv = verResult.getParams().get("iv");
        String code = verResult.getParams().get("code");
        Map params = new HashMap<>();
        params.put("appid", appId);
        params.put("secret", secret);
        params.put("js_code", code);
        params.put("grant_type", "authorization_code");
        try {
            // 向微信服务器发送post请求获取加密了的内容   
            String jsonStr= HTTPSocketFactory
                    .postHttp2("https://api.weixin.qq.com/sns/jscode2session",
                            params)
                    .getObject();
            JSONObject jsonObject = JSON.parseObject(jsonStr);
            String sessionkey = jsonObject.getString("session_key");
            // 解密
            byte[] encrypData = Base64Utils.decodeFromString(encrypted);
            byte[] ivData = Base64Utils.decodeFromString(iv);
            byte[] sessionKey1 = Base64Utils.decodeFromString(sessionkey);
            AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivData);
            //java中自带的是PKCS5Padding填充,通过添加BouncyCastle组件来支持PKCS7Padding填充。
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
            SecretKeySpec keySpec = new SecretKeySpec(sessionKey1, "AES");
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
            String resultString = new String(cipher.doFinal(encrypData), "UTF-8");
            JSONObject object = JSONObject.parseObject(resultString);
            // 拿到手机号码
            String phone = object.getString("phoneNumber");
            JSONObject returnObject = new JSONObject();
            returnObject.put("phone", phone);
            return Result.newSuccess(returnObject);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.newFailure(-1, "获取手机号异常失败");
        }
    }

遇到的错误:

javax.crypto.BadPaddingException: Given final block not properly pad

java.security.NoSuchAlgorithmException: Cannot find any provider supporting AES/CBC/PKCS7Padding

java.security.InvalidAlgorithmParameterException: ECB mode cannot use IV

java.lang.IllegalArgumentException: Last unit does not have enough valid bits

javax.crypto.BadPaddingException: pad block corrupted

偶尔报:javax.crypto.BadPaddingException: pad block corrupted

并且运行到这一句报的错:Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding","BC");

https://blog.csdn.net/zhanglf02/article/details/100124091

参考博客:

[1] https://blog.csdn.net/yuanhangLVli/article/details/82152178

[2] https://www.jianshu.com/p/2853b21fb42e

[3] https://blog.csdn.net/dywailly/article/details/46861777

[4] https://www.jianshu.com/p/f8cd7391d641

你可能感兴趣的:(Java获取微信用户绑定的手机号)