前言
进击微信小程序,最初找到腾讯云给的解决方案,无奈后端是node.js,而且才一开始配上去还不能用,之后仔细看readme,摸到它开源的Wafer,本来以为找到终极解决方案了,仔细看后,发现提供的java方面仅有业务服务器端的代码(要不要如此“歧视”= =),会话服务器只有一个php版的,信道服务。。就更不用说了。于是乎只能自己啃了。 正庆幸之前看过一点php基础,等走到加密解密那,满心欢喜的下载完实例代码,吃惊的发现里面居然有没有java(此时内心可谓是一群动物在奔腾)。但是在崩溃也得向前啊,于是只能默默忍受着十万点真实伤害去搜索相关的解密方式。万幸的是,终于找到了个类似的,接着对照wafer的php版七改八改,还真完成了。 到目前为止实现了java版会话服务器端的移植,至于信道服务,由于暂时接到新需求,无法继续探索,只好暂时作罢,待过段时间继续来过。至于放出的嘛。。暂时就只有这个解密代码,完整的java会话还是过段时间有心情再放出吧,反正这个有了,小伙伴们估计很快也能完成自己的,而且。。毕竟公司都没来得及用上呢(不服?来咬我呀= =)。
这么萌你真的忍心么= =
主体
所需依赖
只需要一个jar包 maven可直接使用
<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on --> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.55</version> </dependency>非maven,可直接下载 下载地址:http://www.bouncycastle.org/archive/139/bcprov-jdk16-139.jar
加解密类代码
[toggle hide=“no” title="" color=""]
import org.bouncycastle.jce.provider.BouncyCastleProvider;import org.bouncycastle.util.Arrays;
import javax.crypto.Cipher;import javax.crypto.NoSuchPaddingException;import javax.crypto.spec.IvParameterSpec;import javax.crypto.spec.SecretKeySpec;import java.security.Key;import java.security.NoSuchAlgorithmException;import java.security.NoSuchProviderException;import java.security.Security;
/** * Created by wind on 2016/12/24. */
/** * * @author ngh * AES128 算法 * * CBC 模式 * * PKCS7Padding 填充模式 * * CBC模式需要添加一个参数iv--对称解密算法初始向量 iv * * 介于java 不支持PKCS7Padding,只支持PKCS5Padding 但是PKCS7Padding 和 PKCS5Padding 没有什么区别 * 要实现在java端用PKCS7Padding填充,需要用到bouncycastle组件来实现 */public class Pkcs7Encoder { // 算法名称 static final String KEY_ALGORITHM = "AES"; // 加解密算法/模式/填充方式 static final String algorithmStr = "AES/CBC/PKCS7Padding"; private static Key key; private static Cipher cipher; boolean isInited = false;
//默认对称解密算法初始向量 iv static byte[] iv = { 0x30, 0x31, 0x30, 0x32, 0x30, 0x33, 0x30, 0x34, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37, 0x30, 0x38 };
public static void init(byte[] keyBytes) {
// 如果密钥不足16位,那么就补足. 这个if 中的内容很重要 int base = 16; if (keyBytes.length % base != 0) { int groups = keyBytes.length / base + (keyBytes.length % base != 0 ? 1 : 0); byte[] temp = new byte[groups * base]; Arrays.fill(temp, (byte) 0); System.arraycopy(keyBytes, 0, temp, 0, keyBytes.length); keyBytes = temp; } // 初始化 Security.addProvider(new BouncyCastleProvider()); // 转化成JAVA的密钥格式 key = new SecretKeySpec(keyBytes, KEY_ALGORITHM); try { // 初始化cipher cipher = Cipher.getInstance(algorithmStr, "BC"); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchPaddingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchProviderException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 加密方法 * --使用默认iv时 * @param content * 要加密的字符串 * @param keyBytes * 加密密钥 * @return */ public static byte[] encrypt(byte[] content, byte[] keyBytes) { byte[] encryptedText = encryptOfDiyIV(content,keyBytes,iv); return encryptedText; }
/** * 解密方法 * --使用默认iv时 * @param encryptedData * 要解密的字符串 * @param keyBytes * 解密密钥 * @return */ public static byte[] decrypt(byte[] encryptedData, byte[] keyBytes) { byte[] encryptedText = decryptOfDiyIV(encryptedData,keyBytes,iv); return encryptedText; } /** * 加密方法 * ---自定义对称解密算法初始向量 iv * @param content * 要加密的字符串 * @param keyBytes * 加密密钥 * @param ivs * 自定义对称解密算法初始向量 iv * @return 加密的结果 */ public static byte[] encryptOfDiyIV(byte[] content, byte[] keyBytes, byte[] ivs) { byte[] encryptedText = null; init(keyBytes); System.out.println("IV:" + new String(ivs)); try { cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(ivs)); encryptedText = cipher.doFinal(content); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return encryptedText; } /** * 解密方法 * * @param encryptedData * 要解密的字符串 * @param keyBytes * 解密密钥 * @param ivs * 自定义对称解密算法初始向量 iv * @return */ public static byte[] decryptOfDiyIV(byte[] encryptedData, byte[] keyBytes,byte[] ivs) { byte[] encryptedText = null; init(keyBytes); System.out.println("IV:" + new String(ivs)); try { cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(ivs)); encryptedText = cipher.doFinal(encryptedData); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return encryptedText; }}[/toggle]
测试结果
测试类中的Base64解码是将java8的Base64加解码封装了一下,请根据实际情况自行完成解码工作(解码的jar与方法太多了,就不在这统一了)。
测试类
[toggle hide=“no” title=“测试类” color=""]
public class Test {
public static void main(String[] args) { String encryptedData = "CiyLU1Aw2KjvrjMdj8YKliAjtP4gsMZMQmRzooG2xrDcvSnxIMXFufNstNGTyaGS9uT5geRa0W4oTOb1WT7fJlAC+oNPdbB+3hVbJSRgv+4lGOETKUQz6OYStslQ142dNCuabNPGBzlooOmB231qMM85d2/fV6ChevvXvQP8Hkue1poOFtnEtpyxVLW1zAo6/1Xx1COxFvrc2d7UL/lmHInNlxuacJXwu0fjpXfz/YqYzBIBzD6WUfTIF9GRHpOn/Hz7saL8xz+W//FRAUid1OksQaQx4CMs8LOddcQhULW4ucetDf96JcR3g0gfRK4PC7E/r7Z6xNrXd2UIeorGj5Ef7b1pJAYB6Y5anaHqZ9J6nKEBvB4DnNLIVWSgARns/8wR2SiRS7MNACwTyrGvt9ts8p12PKFdlqYTopNHR1Vf7XjfhQlVsAJdNiKdYmYVoKlaRv85IfVunYzO0IKXsyl7JCUjCpoG20f0a04COwfneQAGGwd5oa+T8yO5hzuyDb/XcxxmK01EpqOyuxINew=="; String iv="r7BXXKkLb8qrSNn05n0qiA=="; String appid = "wx4f4bc4dec97d474b"; String sessionKey = "tiihtNczf5v6AKRyjwEUhQ=="; toStr(appid,sessionKey,encryptedData,iv); }
private static void toStr(String appid,String sessionKey,String encryptedData ,String iv){ byte[] sessionKeyBy = Base64Util.decode(sessionKey); byte[] encryptedDataBy = Base64Util.decode(encryptedData); byte[] ivBy = Base64Util.decode(iv); byte[] dec = Pkcs7Encoder.decryptOfDiyIV(encryptedDataBy, sessionKeyBy,ivBy); JSONObject h = new JSONObject(new String(dec)); if(h.has("openId")){ System.out.println("解密后的内容:" +h.toString() ); }
}
}[/toggle]

评论