微信小程序中用户信息解密

因为要通过用户信息是加密的内容,所以需要对信息进行解密,原本用JFinal的封装好的方法进行解密,但是一直报错,所以在网上整合了一下别人的代码,并完成了解密,现在把代码贴出来,以供大家和自己以后使用。


首先需要的架包:

 <!-- 解密需要用的jar  -->
    <dependency>
      <groupId>org.bouncycastle</groupId>
      <artifactId>bcprov-jdk15on</artifactId>
      <version>1.57</version>
    </dependency>

  1. 需要注意的是,AES解密的时候需要用到javax.crypto.*包的类,在jdk的 jce.jar中提供,是jdk自带的库。如果是MAVEN项目,则需要在pom.xml文件中配置指定编译路径jce.jar

在bootclasspath中添加jce.jar的地址:<bootclasspath>${JAVA_HOME}/jre/lib/rt.jar:${JAVA_HOME}/jre/lib/jce.jar</bootclasspath> ,注意rt.jar 和 jce.jar 间以:号连接

如:

<build>
  <finalName>com.yfs.app</finalName>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>2.5.1</version>
      <configuration>
        <source>1.7</source>
        <target>1.7</target>
        <compilerArguments>
          <verbose />
          <bootclasspath>${JAVA_HOME}/jre/lib/rt.jar:${JAVA_HOME}/jre/lib/jce.jar</bootclasspath>
        </compilerArguments>
        <encoding>utf-8</encoding>
      </configuration>
    </plugin>

  </plugins>
</build>

这些都配置好以后,就可以写一个解密的工具类了

package com.jmt.wx.util;

import com.alibaba.fastjson.JSONObject;
import com.jfinal.weixin.sdk.api.ApiResult;
import com.jfinal.weixin.sdk.encrypt.WxaBizDataCrypt;
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
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 java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.spec.InvalidParameterSpecException;
import java.util.Arrays;

/**
 * Created by yfs on 2017/2/6.
 * <p>
 * AES-128-CBC 加密方式
 * 注:
 * AES-128-CBC可以自己定义“密钥”和“偏移量“。
 * AES-128是jdk自动生成的“密钥”。
 */
public class JieMiUtil {

    static {
        //BouncyCastle是一个开源的加解密解决方案,主页在http://www.bouncycastle.org/
        Security.addProvider(new BouncyCastleProvider());
    }

    /**
     * AES解密
     *
     * @param data           //密文,被加密的数据
     * @param key            //秘钥
     * @param iv             //偏移量
     * @param encodingFormat //解密后的结果需要进行的编码
     * @return
     * @throws Exception
     */
    public static String decrypt(String data, String key, String iv, String encodingFormat) throws Exception {
//        initialize();

        //被加密的数据
        byte[] dataByte = Base64.decodeBase64(data);
        //加密秘钥
        byte[] keyByte = Base64.decodeBase64(key);
        //偏移量
        byte[] ivByte = Base64.decodeBase64(iv);


        try {
            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, encodingFormat);
                return result;
            }
            return null;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidParameterSpecException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return null;
    }

}


redisTemplate工具类:

扫描二维码关注公众号,回复: 1450176 查看本文章
package com.jmt.wx.util;

import java.util.Date;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;

public class CacheUtil{
	
	@Autowired
	private StringRedisTemplate redisTemplate;//redis操作模板
	
		
	public void put(String key, String value) {
		if (key==null || "".equals(key)) {
			return;
		}
		redisTemplate.opsForHash().put(key, key, value);
	}
	

	public String get(String key) {
		Object obj = redisTemplate.opsForValue().get(key);
		if(obj == null){
			return null;
		}else{
			return String.valueOf(obj);
		}
	}
	public void expire(String key,String value,long time,TimeUnit timeUnit ){
		
		redisTemplate.opsForValue().set(key, value, time, timeUnit);
	}
	/*
	 * 销毁
	 */
	public void delete(String key){
		
		redisTemplate.delete(key);
	}

	/**
	 * 根据key 获取指定单位的过期时间
	 */
	public long getTimeByKey(String Key){
	

		long time2=redisTemplate.boundHashOps(Key).getExpire();
				return time2;
	}

	public long getOutTime(String key){
		long time=redisTemplate.getExpire(key);
		return time;
	}

	/**
	 * 检查key是否存在
	 * 如果不存在,证明没有session
	 */
	public boolean CheckSession(String  key){
		return  redisTemplate.hasKey(key);
	}
}






服务端代码:


 /**
     * 服务端解密用户信息接口
     * 获取unionId
     * return unionid 返回获取的unionID
     */
    public void encryptedData() {
        JSONObject returnInfo = new JSONObject();
        String encryptedData = getPara("encryptedData");
        String iv = getPara("iv");

        String code = getPara("code");

        //登录凭证不能为空
        if (code == null || code.length() == 0) {
            returnInfo.put("status", 0);
            returnInfo.put("msg", "code 不能为空");
            renderJson(returnInfo);
            return;
        }


        //小程序唯一标识   (在微信小程序管理后台获取)
        String wxspAppid = "*********************";
        //小程序的 app secret (在微信小程序管理后台获取)
        String wxspSecret = "********************";
        //授权(必填)
        String grant_type = "authorization_code";

///////////////////////////////////////////////////

        // 调用微信api,用code 换取openId和session_key
        // 返回示例{"session_key":"ycGF02Ha\/dnZ6Tc829xw7Q==","expires_in":7200,"openid":"oZ2Xq0Byh0wqtUi-j-RgJ1atLPdo"}
        String url = "https://api.weixin.qq.com/sns" + "/jscode2session?appid="
                + wxspAppid + "&" + "secret=" + wxspSecret + "&js_code=" + code
                + "&" +grant_type;
        CloseableHttpClient httpClient = HttpClients.createDefault();

        HttpGet httpget = new HttpGet(url);
        String sessionKey=null;
        try {
            CloseableHttpResponse response = httpClient.execute(httpget);
            int statusCode = response.getStatusLine().getStatusCode();
            JSONObject resultJson = null;
            if (statusCode == HttpStatus.SC_OK) {

                String reslut = EntityUtils.toString(response.getEntity());

                resultJson = JSONObject.parseObject(reslut);

                 sessionKey = resultJson.getString("session_key");
                String openid = resultJson.getString("openid");

                //添加session到redis缓存中
                //把sessionKey和APPId设置成session,这里用的是redisTemplate模板
                String Third_session=null;
                if (sessionKey != null && openid != null) {
                     Third_session = SessionUtil.generateSessionId();//随机生成长度为16B

                    cacheUtil.expire(Third_session, sessionKey+openid, Integer.parseInt(Gloal.getProperty("CACHE_TIME")), TimeUnit.SECONDS);
                    System.out.println(new Date() + "设置sessionKey:"
                            + Third_session);
                    System.out.println(new Date() + "设置sessionValue:"
                            + sessionKey + openid);

                }

                //////////////// 2、对encryptedData加密数据进行AES解密 ////////////////

                String result = JieMiUtil.decrypt(encryptedData, sessionKey, iv, "UTF-8");
                if (null != result && result.length() > 0) {
                    returnInfo.put("errCode",ErrCode.SUCCESS);
                    returnInfo.put("msg", "解密成功");

                    JSONObject userInfoJSON = JSONObject.parseObject(result);
                    Map userInfo = new HashMap();
                    userInfo.put("openId", userInfoJSON.get("openId"));
                    userInfo.put("nickName", userInfoJSON.get("nickName"));
                    userInfo.put("gender", userInfoJSON.get("gender"));
                    userInfo.put("city", userInfoJSON.get("city"));
                    userInfo.put("province", userInfoJSON.get("province"));
                    userInfo.put("country", userInfoJSON.get("country"));
                    userInfo.put("avatarUrl", userInfoJSON.get("avatarUrl"));
                    userInfo.put("unionId", userInfoJSON.get("unionId"));
                    userInfo.put("third_session",Third_session);
                    returnInfo.put("userInfo", userInfo);
                    renderJson(returnInfo);
                    return;
                }
            }

            /////////////////////////////////////////////
            returnInfo.put("errCode", ErrCode.RESULT_NULL);
            returnInfo.put("msg", "fail");
            renderJson(returnInfo);
            return;

        } catch (Exception e) {
            e.printStackTrace();
            returnInfo.put("errCode", ErrCode.RESULT_NULL);
            returnInfo.put("msg", "fail");
            renderJson(returnInfo);
            return;
        }finally {
            if (httpget != null) {
                httpget.releaseConnection();
            }
        }

    }


到此为止,用户信息解密成功。


总结

好了,总算完成数据解密了,接下来对接新的或已有的用户系统都妥妥的。

有一点需要注意的是,要对接已有的用户系统可能需要用到unionId,如果通过以上方法获取不到unionId,那么你就要去检查一下你的微信开放平台(微信开放平台)是否有绑定微信小程序咯~

本文借鉴了 微信小程序联盟 的文章,有想看的可以去看下哦





猜你喜欢

转载自blog.csdn.net/qq_35357001/article/details/77966567