微信小程式開放資料解密 AES-128-CBC 解密(Java版本)
阿新 • • 發佈:2018-11-03
最近朋友在弄微信小程式開發,需要跟微信服務端互動,微信敏感資料都有加密返回,需要在服務端接收進行解密後再返回給客戶端小程式,今天就通過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(); } } }