• 微信小程序获取用户手机号


    一、微信小程序获取用户手机号分四步:

    1.微信前端登录接口wx.login获取临时登录凭证code

    微信文档 https://developers.weixin.qq.com/miniprogram/dev/api/open-api/login/wx.login.html

    2.后台根据code换取sessionKey

    URL:https://api.weixin.qq.com/sns/jscode2session?appid={appId}&secret={appSecret}&grant_type=authorization_code&js_code={code}

    该接口同时也会返回 openId和unionid

    微信参考文档 https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html

    3.前端获取到encryptedData、iv

    使用微信小程序的组件 button,open-type值为getPhoneNumber。

    微信文档 https://developers.weixin.qq.com/miniprogram/dev/component/button.html

                 https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getPhoneNumber.html

    4.encryptedData、iv、sessionKey三个参数调用后台解密接口解密即可得到微信小程序用户手机号

    这一步有坑,详见下面

    Java版解密工具类demo:

    package com.meritdata.cloud.middleplatform.dataservice.cashier.utils;
    
    import org.apache.commons.codec.binary.Base64;
    import org.bouncycastle.jce.provider.BouncyCastleProvider;
    import sun.misc.BASE64Decoder;
    import sun.misc.BASE64Encoder;
    
    import javax.crypto.*;
    import javax.crypto.spec.DESKeySpec;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.SecretKeySpec;
    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    import java.security.*;
    import java.security.spec.InvalidKeySpecException;
    import java.security.spec.InvalidParameterSpecException;
    import java.util.Arrays;
    
    
    /**
     * 2020/12/14 5:08 PM
     *
     * @author shoo
     * @describe 解密工具类
     */
    public class SecretUtilTools {
        public SecretUtilTools() {
        }
    
        public static String encryptForDES(String souce, String key) throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
            SecureRandom sr = new SecureRandom();
            DESKeySpec dks = new DESKeySpec(key.getBytes("UTF-8"));
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey key1 = keyFactory.generateSecret(dks);
            Cipher cipher = Cipher.getInstance("DES");
            cipher.init(1, key1, sr);
            byte[] encryptedData = cipher.doFinal(souce.getBytes("UTF-8"));
            String base64Str = (new BASE64Encoder()).encode(encryptedData);
            return base64Str;
        }
    
        public static String decryptForDES(String souce, String key) throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, IOException, IllegalBlockSizeException, BadPaddingException {
            SecureRandom sr = new SecureRandom();
            DESKeySpec dks = new DESKeySpec(key.getBytes());
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey key1 = keyFactory.generateSecret(dks);
            Cipher cipher = Cipher.getInstance("DES");
            cipher.init(2, key1, sr);
            byte[] encryptedData = (new BASE64Decoder()).decodeBuffer(souce);
            byte[] decryptedData = cipher.doFinal(encryptedData);
            return new String(decryptedData, "UTF-8");
        }
    
        public static String decrypt(String data, String key, String iv, String encodingFormat) throws Exception {
            byte[] dataByte = Base64.decodeBase64(data);
            byte[] keyByte = Base64.decodeBase64(key);
            byte[] ivByte = Base64.decodeBase64(iv);
            int base = 16;
            if (keyByte.length % base != 0) {
                int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0);
                byte[] temp = new byte[groups * base];
                Arrays.fill(temp, (byte)0);
                System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
                keyByte = temp;
            }
    
            try {
                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(2, spec, parameters);
                byte[] resultByte = cipher.doFinal(dataByte);
                if (null != resultByte && resultByte.length > 0) {
                    String result = new String(resultByte, encodingFormat);
                    return result;
                }
    
                return null;
            } catch (NoSuchAlgorithmException var13) {
                var13.printStackTrace();
            } catch (NoSuchPaddingException var14) {
                var14.printStackTrace();
            } catch (InvalidParameterSpecException var15) {
                var15.printStackTrace();
            } catch (InvalidKeyException var16) {
                var16.printStackTrace();
            } catch (InvalidAlgorithmParameterException var17) {
                var17.printStackTrace();
            } catch (IllegalBlockSizeException var18) {
                var18.printStackTrace();
            } catch (BadPaddingException var19) {
                var19.printStackTrace();
            } catch (UnsupportedEncodingException var20) {
                var20.printStackTrace();
            }
    
            return null;
        }
    }

       调用方法:

        public static MinAppUser getMiniUserInfo(String encryptedData, String iv, String sessionKey) throws IOException {
            MinAppUser minAppUser = new MinAppUser();
            String result = "";
    
            try {
                result = SecretUtilTools.decrypt(encryptedData, sessionKey, iv, "UTF-8");
                if (null != result && result.length() > 0) {
                    minAppUser = (MinAppUser)(new ObjectMapper()).readValue(result, MinAppUser.class);
    
                } else {
                    System.out.println("getMiniUserInfo error");
                }
            } catch (Exception var11) {
                var11.printStackTrace();
            }
            return minAppUser;
        }

    二、以上四步步骤顺序不能错,否则各种报错。如:

    1.解密报错 pad block corrupted

    2.解密那一步,通过URL传参,不知道什么机制会自动把 "+" 换成 " ",导致你的encryptedData、iv错误。解决方法是反替换:

    encryptedData = encryptedData.replaceAll(" ","+");
    iv = iv.replaceAll(" ","+");
    stay hungry stay foolish!
  • 相关阅读:
    Jmeter之参数化
    安全测试-业务安全的些许“瞎说”
    (转)LR性能测试结果样例分析
    (转)使用 Nmon 监控 Linux 的系统性能
    Jmeter之断言
    自动化框架httpClient实例
    RabbitMQ集群 Docker一键部署
    使用swing构建一个界面(包含flow ,Border,Grid,card ,scroll布局)
    Jtable实现
    java 使用最新api操作mongodb
  • 原文地址:https://www.cnblogs.com/shog808/p/14179102.html
Copyright © 2020-2023  润新知