java签名验证_JAVA版⼩程序⽤户数据的签名验证和
加解密
签名验证和加解密
数据签名校验
为了确保 开放接⼝ 返回⽤户数据的安全性,会对明⽂数据进⾏签名。开发者可以根据业务需要对数据包进⾏签名校验,确保数据的完整性。
签名校验算法涉及⽤户的session_key,通过 wx.login 登录流程获取⽤户session_key,并⾃⾏维护与应⽤⾃⾝登录态的对应关系。
通过调⽤接⼝(如 wx.getUserInfo)获取数据时,接⼝会同时返回 rawData、signature,其中 signature = sha1( rawData +
session_key )
开发者将 signature、rawData 发送到开发者服务器进⾏校验。服务器利⽤⽤户对应的 session_key 使⽤相同的算法计算出签名signature2 ,⽐对 signature 与 signature2 即可校验数据的完整性。
加密数据解密算法
接⼝如果涉及敏感数据(如wx.getUserInfo当中的 openId 和unionId ),接⼝的明⽂内容将不包含这些敏感数据。开发者如需要获取敏感数据,需要对接⼝返回的加密数据( encryptedData )进⾏对称解密。解密算法如下:
对称解密使⽤的算法为 AES-128-CBC,数据采⽤PKCS#7填充。
对称解密的⽬标密⽂为 Base64_Decode(encryptedData),
对称解密秘钥 aeskey = Base64_Decode(session_key), aeskey 是16字节
对称解密算法初始向量 iv 会在数据接⼝中返回。
官⽅提供了多种编程语⾔的⽰例代码( 点击下载 ),但就是没提供JAVA版本的,可能的确PHP是最好的语⾔,腾讯提供的demo好多都是PHP版本的。
JAVA代码案例
commons-codec
commons-codec
1.10
com.alibaba
fastjson
1.2.7
org.bouncycastle
bcprov-jdk15on
1.57
我们可以参考PHP给出的代码,使⽤JAVA实现: AESUtil:
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.AlgorithmParameters;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;
pto.BadPaddingException;
pto.Cipher;
session下载pto.IllegalBlockSizeException;
pto.NoSuchPaddingException;
pto.spec.IvParameterSpec;
pto.spec.SecretKeySpec;
/**
* AES解密
* 创建者 柒
* 创建时间2018年3⽉12⽇
*/
public class AESUtil {
static {
Security.addProvider(new BouncyCastleProvider());
}
/
**
* AES解密
* @param content 密⽂
* @return
* @throws InvalidAlgorithmParameterException
* @throws NoSuchProviderException
*/
public static byte[] decrypt(byte[] content, byte[] keyByte, byte[] ivByte) throws InvalidAlgorithmParameterException {
try {
Cipher cipher = Instance("AES/CBC/PKCS7Padding");
Key sKeySpec = new SecretKeySpec(keyByte, "AES");
//⽣成iv
AlgorithmParameters params = Instance("AES");
params.init(new IvParameterSpec(ivByte));
cipher.init(Cipher.DECRYPT_MODE, sKeySpec, params);// 初始化return cipher.doFinal(content);
} 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 (Exception e) {
e.printStackTrace();
}
return null;
}
}
WXBizDataCrypt:
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import dec.binary.Base64;
import org.apachemons.lang.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
/**
* 对⼩程序⽤户加密数据的解密
* 创建者 柒
* 创建时间 2018年3⽉12⽇
*/
public class WXBizDataCrypt {
public static String illegalAesKey = "-41001";//⾮法密钥
public static String illegalIv = "-41002";//⾮法初始向量
public static String illegalBuffer = "-41003";//⾮法密⽂
public static String decodeBase64Error = "-41004"; //解码错误
public static String noData = "-41005"; //数据不正确
private String appid;
private String sessionKey;
public WXBizDataCrypt(String appid, String sessionKey) {
this.appid = appid;
this.sessionKey = sessionKey;
}
/
**
* 检验数据的真实性,并且获取解密后的明⽂.
* @param encryptedData string 加密的⽤户数据
* @param iv string 与⽤户数据⼀同返回的初始向量
* @return data string 解密后的原⽂
* @return String 返回⽤户信息
*/
public String decryptData(String encryptedData, String iv) {
if (StringUtils.length(sessionKey) != 24) {
return illegalAesKey;
}
/
/ 对称解密秘钥 aeskey = Base64_Decode(session_key), aeskey 是16字节。byte[] aesKey = Base64.decodeBase64(sessionKey);
if (StringUtils.length(iv) != 24) {
return illegalIv;
}
// 对称解密算法初始向量 为Base64_Decode(iv),其中iv由数据接⼝返回。
byte[] aesIV = Base64.decodeBase64(iv);
// 对称解密的⽬标密⽂为 Base64_Decode(encryptedData)
byte[] aesCipher = Base64.decodeBase64(encryptedData);
try {
byte[] resultByte = AESUtil.decrypt(aesCipher, aesKey, aesIV);
if (null != resultByte && resultByte.length > 0) {
String userInfo = new String(resultByte, "UTF-8");
JSONObject jsons = JSON.parseObject(userInfo);
String id = JSONObject("watermark").getString("appid"); if (!StringUtils.equals(id, appid)) {
return illegalBuffer;
}
return userInfo;
} else {
return noData;
}
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
/**
* encryptedData 和 iv 两个参数通过⼩程序wx.getUserInfo()⽅法获取* @param args
* @see
*/
public static void main(String[] args) {
String appId = "wx4f4bc4dec97d474b";
String sessionKey = "tiihtNczf5v6AKRyjwEUhQ==";
String encryptedData = "CiyLU1Aw2KjvrjMdj8YKliAjtP4gsMZM" + "QmRzooG2xrDcvSnxIMXFufNstNGTyaGS"
+ "9uT5geRa0W4oTOb1WT7fJlAC+oNPdbB+"
+ "3hVbJSRgv+4lGOETKUQz6OYStslQ142d"
+ "NCuabNPGBzlooOmB231qMM85d2/fV6Ch"
+ "evvXvQP8Hkue1poOFtnEtpyxVLW1zAo6"
+ "/1Xx1COxFvrc2d7UL/lmHInNlxuacJXw"
+ "u0fjpXfz/YqYzBIBzD6WUfTIF9GRHpOn"
+ "/Hz7saL8xz+W//FRAUid1OksQaQx4CMs"
+ "8LOddcQhULW4ucetDf96JcR3g0gfRK4P"
+ "C7E/r7Z6xNrXd2UIeorGj5Ef7b1pJAYB"
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论