微信小程序Java后台解密

前几天要做一个信息小程序获取用户的手机号码的功能,但是发现,拿到的数据都是加密的,官方并没有提供Java后台的源代码。。。找到了很久,看到这篇文章,学习了,然后在这基础上做了一些修改,emmm是一些修改。

后台用的spring boot框架,所以有些包如果没有的,请自行导入

前台小程序index.js

Page({
  onLoad: function () {
    var that = this
    that.login();
  },
/*解密的类型1、用户信息,2、手机号码*/
  decode: function (deType) {
    var that = this
    wx.request({
      url: 'http://localhost:8765/decode',
      data: {
        'encryptedData': that.data.encryptedData,
        'iv': that.data.iv,
        'session_key': wx.getStorageSync('session_key')
      },
      method: 'GET', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
      // header: {}, // 设置请求的 header
      success: function (res) {
        // success
        that.setData({ decode: res.data.Decode});
        if (deType == 2) {
          console.log(res)
        }
      }
    })
  },
  getPhoneNumber: function (e) {
    var that = this
    wx.checkSession({
      // success: function () {
      //   //session_key 未过期,并且在本生命周期一直有效
      // },
      fail: function () {
        // session_key 已经失效,需要重新执行登录流程
        that.login() //重新登录
      }
    })

    that.setData({ iv: e.detail.iv })
    that.setData({ encryptedData: e.detail.encryptedData })
    that.decode(2)
  },
  login: function () {
    var that = this
    wx.login({
      success: function (res) {
        // success
        var code = res.code
        if (code) {
          that.setData({ code: code })
          wx.request({
            url: 'https://api.weixin.qq.com/sns/jscode2session?appid='+你的小程序的appid+'f&secret=' + 你的小程序的secret + '&js_code=' + code + '&grant_type=authorization_code',
            /*appid和secret都是生成的固定的*/
            success: function (res) {
              that.setData({ openid: res.data.openid })
              that.setData({ session_key: res.data.session_key })
              wx.setStorageSync('session_key', res.data.session_key)
              wx.getUserInfo({
                success: function (res) {
                  // success
                  that.setData({ userInfo: res.userInfo })
                  that.setData({ iv: res.iv })
                  that.setData({ encryptedData: res.encryptedData })

                  that.decode(1)
                }
              })
            }
          })
        }
      }
    })
  }
})

如果要获取手机号码需要在页面上加个按钮

<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">获取手机号码</button>

maven依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-rest</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-devtools</artifactId>
           <optional>true</optional>
       </dependency>
       <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-jdk16</artifactId>
        <version>1.46</version>
    </dependency>
    <dependency>  
        <groupId>com.alibaba</groupId>  
        <artifactId>fastjson</artifactId>  
        <version>1.2.28</version>  
    </dependency> 
    <!-- JSONObject对象依赖的jar包 -->  
       <dependency>  
           <groupId>commons-beanutils</groupId>  
           <artifactId>commons-beanutils</artifactId>  
           <version>1.9.3</version>  
       </dependency>  
       <dependency>  
           <groupId>commons-collections</groupId>  
           <artifactId>commons-collections</artifactId>  
           <version>3.2.1</version>  
       </dependency>  
       <dependency>  
           <groupId>commons-lang</groupId>  
           <artifactId>commons-lang</artifactId>  
           <version>2.6</version>  
       </dependency>  
       <dependency>  
           <groupId>commons-logging</groupId>  
           <artifactId>commons-logging</artifactId>  
           <version>1.1.1</version>  
       </dependency>  
       <dependency>  
           <groupId>net.sf.ezmorph</groupId>  
           <artifactId>ezmorph</artifactId>  
           <version>1.0.6</version>  
       </dependency>  
    <dependency>
        <groupId>net.sf.json-lib</groupId>
        <artifactId>json-lib</artifactId>
        <version>2.4</version>
        <classifier>jdk15</classifier>
    </dependency>
       <!-- Json依赖架包下载 -->  
</dependencies>

DecodeController.java

import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.util.HashMap;
import java.util.Map;

import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.demo.utils.AESUtil;

import net.sf.json.JSONObject;

@RestController
@CrossOrigin(origins="*",allowCredentials="true",maxAge=360)
public class DecodeController {

    /**
     * 
     * @param encryptedData 需要解密的密文,可以是用户信息或者手机号码,或者其它
     * @param iv 加密算法的初始向量
     * @param session_key 会话密钥
     * @return
     */
    @RequestMapping(value="decode")
    public Map<String, Object> decode(String encryptedData,String iv,String session_key){
        Map<String, Object> map = new HashMap<String, Object>();

        try {
            byte[] resultByte = AESUtil.instance.decrypt(Base64.decodeBase64(encryptedData), Base64.decodeBase64(session_key), Base64.decodeBase64(iv));
            if(null != resultByte && resultByte.length > 0){
                String userInfo = new String(resultByte, "UTF-8");
                JSONObject json = JSONObject.fromObject(userInfo); 
                map.put("Decode", json);
            }
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return map;
    }
}

AESUtil.java
这里要注意,一般情况下谁都会报错,所以要加一些东西 详情请查看借鉴

Java本身限制密钥的长度最多128位,而AES256需要的密钥长度是256位,因此需要到Java官网上下载一个Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files。

官方网站提供了JCE无限制权限策略文件的下载:
JDK6的下载地址:
http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html

JDK7的下载地址:
http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html

JDK8的下载地址:
http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html

下载后解压,可以看到local_policy.jar和US_export_policy.jar以及readme.txt。
如果安装了JRE,将两个jar文件放到%JRE_HOME%\lib\security下覆盖原来文件,记得先备份。
如果安装了JDK,将两个jar文件也放到%JDK_HOME%\jre\lib\security下。

只要做了以上两步,就能正常加解密了。
如果还不行,可以参考这篇文章,里面提供了完整详细的例子和测试用例:
https://www.cnblogs.com/jhuangsjtu/p/8261683.html

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.security.*;

public class AESUtil {
    public static final AESUtil instance = new AESUtil();

    public static boolean initialized = false;

    /**
     * AES解密
     * @param content 密文
     * @return 解密后的字符串
     * @throws InvalidAlgorithmParameterException
     * @throws NoSuchProviderException
     */
    public byte[] decrypt(byte[] content, byte[] keyByte, byte[] ivByte) throws InvalidAlgorithmParameterException {
        initialize();
        try {
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
            Key sKeySpec = new SecretKeySpec(keyByte, "AES");

            cipher.init(Cipher.DECRYPT_MODE, sKeySpec, generateIV(ivByte));// 初始化
            byte[] result = cipher.doFinal(content);
            return result;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (NoSuchProviderException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    public static void initialize(){
        if (initialized) return;
        Security.addProvider(new BouncyCastleProvider());
        initialized = true;
    }
    //生成iv
    public static AlgorithmParameters generateIV(byte[] iv) throws Exception{
        AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
        params.init(new IvParameterSpec(iv));
        return params;
    }
}

喝水不忘挖井人,原文借鉴 如有意见,请联系删除

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值