⼩程序encryptedData的解密(JAVA)
上图为官⽅api提供的登陆获取⽤户信息的流程,session_key的得到这⾥不进⾏说明,详情可以看⼩程序的官⽅api。
数据签名校验
为了确保开放接⼝返回⽤户数据的安全性,会对明⽂数据进⾏签名。开发者可以根据业务需要对数据包进⾏签名校验,确保数据的完整性。
通过调⽤接⼝(如 wx.getUserInfo)获取数据时,接⼝会同时返回 rawData、signature,其中 signature = sha1( rawData + session_key )
开发者将 signature、rawData 发送到开发者服务器进⾏校验。服务器利⽤⽤户对应的 session_key 使⽤相同的算法计算出签名 signature2 ,⽐对 signature 与 signature2 即可校验数据的完整性。
以上描述即为⼩程序传过来的 rawData 和已经得到session_key进⾏sha1加密之后的值如果和signature相等的话就表明数据校验通过,
加密数据解密算法
接⼝如果涉及敏感数据(如wx.getUserInfo当中的 openId 和unionId ),接⼝的明⽂内容将不包含这些敏感数据。开发者如需要获取敏感数据,需要对接⼝返回的加密数据( encryptedData )进⾏对称解密。解密算法如下:
对称解密使⽤的算法为 AES-128-CBC,数据采⽤PKCS#7填充。
对称解密的⽬标密⽂为 Base64_Decode(encryptedData)。
对称解密秘钥 aeskey = Base64_Decode(session_key), aeskey 是16字节。
对称解密算法初始向量为Base64_Decode(iv),其中iv由数据接⼝返回。
官⽅提供了多种编程语⾔的⽰例代码(点击下载)。每种语⾔类型的接⼝名字均⼀致。调⽤⽅式可以参照⽰例。
另外,为了应⽤能校验数据的有效性,会在敏感数据加上数据⽔印( watermark )
⼩程序会传来四个数据其中两个为 rawData和 sighnature ,
还有两个为 encryptedData 和 iv有趣的java小程序
encryptedData session_key iv 这三个数据经过特定的解密之后,就可以得到⽤户信息了。
解密的⼯具类:
package cn.iyishuxymon.utils;
import com.alibaba.fastjson.JSONObject;
import s.internal.impl.dv.util.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
pto.Cipher;
pto.spec.IvParameterSpec;
pto.spec.SecretKeySpec;
import java.security.AlgorithmParameters;
import java.security.Security;
import java.util.Arrays;
/**
* @author ljh
*/
public class WXUtils {
public static JSONObject getUserInfo(String encryptedData, String sessionKey, String iv){
/
/ 被加密的数据
byte[] dataByte = Base64.decode(encryptedData);
// 加密秘钥
byte[] keyByte = Base64.decode(sessionKey);
// 偏移量
byte[] ivByte = Base64.decode(iv);
try {
// 如果密钥不⾜16位,那么就补⾜. 这个if 中的内容很重要
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;
}
// 初始化
Security.addProvider(new BouncyCastleProvider());
Cipher cipher = Instance("AES/CBC/PKCS7Padding","BC");
SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
AlgorithmParameters parameters = Instance("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);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
需要注意的是 BouncyCastleProvider包需要⼿动导⼊maven:
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.59</version>
</dependency>
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论