最近朋友在弄微信小程式開發,需要跟微信服務端互動,微信敏感資料都有加密傳回,需要在服務端接收進行解密後再傳回給用戶端小程式,今天就通過Java進行資料的解密,以下展示是Java代碼
如果你使用的C#,請通路這個位址(C#版本) https://blog.csdn.net/jasonsong2008/article/details/83586119
我們先來看一下微信官方的說明文檔,以下直接文檔來自微信小程式官方:
加密資料解密算法
接口如果涉及敏感資料(如
wx.getUserInfo
當中的 openId 和 unionId),接口的明文内容将不包含這些敏感資料。開發者如需要擷取敏感資料,需要對接口傳回的加密資料(encryptedData) 進行對稱解密。 解密算法如下:
- 對稱解密使用的算法為 AES-128-CBC,資料采用PKCS#7填充。
- 對稱解密的目标密文為 Base64_Decode(encryptedData)。
- 對稱解密秘鑰 aeskey = Base64_Decode(session_key), aeskey 是16位元組。
- 對稱解密算法初始向量 為Base64_Decode(iv),其中iv由資料接口傳回。
通過微信文檔的說明編寫了如下解密方法供大家使用
import org.apache.shiro.codec.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* AES解密(JAVA版本)
* Add by 成長的小豬(Jason.Song) on 2018/10/26
* http://blog.csdn.net/jasonsong2008
*/
public class AesHelper {
/**
* 微信小程式 開放資料解密
* AES解密(Base64)
* Add by 成長的小豬(Jason.Song) on 2018/10/26
* @param encryptedData 已加密的資料
* @param sessionKey 解密密鑰
* @param iv IV偏移量
* @return
* @throws Exception
*/
public static String decryptForWeChatApplet(String encryptedData, String sessionKey, String iv) throws Exception {
byte[] decryptBytes = Base64.decode(encryptedData);
byte[] keyBytes = Base64.decode(sessionKey);
byte[] ivBytes = Base64.decode(iv);
return new String(decryptByAesBytes(decryptBytes, keyBytes, ivBytes));
}
/**
* AES解密
* Add by 成長的小豬(Jason.Song) on 2018/10/26
* @param decryptedBytes 待解密的位元組數組
* @param keyBytes 解密密鑰位元組數組
* @param ivBytes IV初始化向量位元組數組
* @return
* @throws Exception
*/
public static byte[] decryptByAesBytes(byte[] decryptedBytes, byte[] keyBytes, byte[] ivBytes) throws Exception {
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
IvParameterSpec iv = new IvParameterSpec(ivBytes);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, key, iv);
byte[] outputBytes = cipher.doFinal(decryptedBytes);;
return outputBytes;
}
}
下面是通過以上解密方法進行測試,大家根據自己的情況進行相應調用即可
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.junit.Assert.*;
/**
* 文章來源于成長的小豬
* http://blog.csdn.net/jasonsong2008
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring/applicationContext.xml"})
public class AesHelperTest {
@Test
public void decryptForWeChatApplet() {
//微信小程式傳回的加密資料
String encryptedData =
"tsyLVebikY1aLQ0aNpg10NHxCTV2Ar+FJHUZdwIchBXFbJU7hXyf5gbDibaLU+lT6bzzut/nVymRFp/U8MrF0c8yOCFbnK5aevyearR7vopeel2y929weVA/s16shDPnRMkIn9xiMfVY3LDmuptnBpy1loZfSW2CPfXFuKXQf2z+Kiruynve1cq2mnzAadNaw3/g/tjHRPzxBnTkMsu8sQ==";
//會話密鑰
String sessionKey = "vBwBswWRVmD0WQvRbdbMZg==";
//解密算法初始向量
String iv = "8IzE0WUF0j5hXy4oIKuLHA==";
try {
String result = AesHelper.decryptForWeChatApplet(encryptedData, sessionKey, iv);
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
}
}
}