吐血記錄微信小程序受權獲取Unionid及linux下使用bouncycastle解密用戶數據 遇到的坑

背景html

公司小程序上線了,發現系統沒法拿到一些用戶的UniondID。可是上線前的測試一切都是正常的。java

坑1linux

經排查,發現一些用戶經過下面的接口沒法獲得unionidapache

https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code小程序

閱讀https://developers.weixin.qq.com/miniprogram/dev/api/uinionID.html 得知,從未在關聯公衆號或小程序進行受權過的用戶,是不會直接返回unionid的。要拿到這些用戶的unionid須要如下3個數據api

1.https://api.weixin.qq.com/sns/jscode2session返回的session_keytomcat

2. wx.getUserInfo且用戶贊成後返回的encryptedData和ivsession

使用如下代碼能夠解密出用戶的信息app

import org.apache.commons.codec.binary.Base64; import org.bouncycastle.jce.provider.BouncyCastleProvider; import java.io.UnsupportedEncodingException; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.Key; import java.security.NoSuchProviderException; import java.security.Security; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; public class AES { public static boolean initialized = false; public static void main(String[] args) throws InvalidAlgorithmParameterException, UnsupportedEncodingException { String encryptedData = ""; String iv = ""; String sessionKey = ""; byte[] resultByte = AES.decrypt(Base64.decodeBase64(encryptedData), Base64.decodeBase64(sessionKey), Base64.decodeBase64(iv)); System.out.println(new String(resultByte,"utf-8")); } /** * AES解密 * * @param content 密文 * @return * @throws InvalidAlgorithmParameterException * @throws NoSuchProviderException */ public static byte[] decrypt(byte[] content, byte[] keyByte, byte[] ivByte) throws InvalidAlgorithmParameterException { initialize(); try { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding"); Key sKeySpec = new SecretKeySpec(keyByte, "AES"); cipher.init(Cipher.DECRYPT_MODE, sKeySpec, generateIV(ivByte));// 初始化 byte[] result = cipher.doFinal(content); return result; } catch (Exception e) { e.printStackTrace(); } return null; } public static void initialize() { if (initialized) return; Security.addProvider(new BouncyCastleProvider()); initialized = true; } //生成iv public static AlgorithmParameters generateIV(byte[] iv) throws Exception { AlgorithmParameters params = AlgorithmParameters.getInstance("AES"); params.init(new IvParameterSpec(iv)); return params; } } 

 

坑2,真正吐血的地方dom

使用以上的方法在我本機上面進行測試是沒問題的,可是將項目部署上Linux上以後又出了一個問題

解密的時候拋異常:

java.security.NoSuchAlgorithmException - Cannot find any provider supporting AES/CBC/PKCS7Padding

我回頭看代碼,要實如今java端用PKCS7Padding填充,須要用到bouncycastle組件來實現,解密代碼中確實也設置了。且本機也是能夠解密的,本機和linux上的jdk均是官網下載的1.8版本,爲何Linux上就不行呢

//使用BouncyCastleProvider組件填充 Security.addProvider(new BouncyCastleProvider());

maven中也引用了bouncycastle

<dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.59</version> </dependency>

 

排除代碼問題的話很明顯是環境問題了,linux上使用Security.addProvider(new BouncyCastleProvider());  不起效果。。。

 

那沒辦法了,只能手動改jre。步驟以下

1.把bcprov-jdk15on-1.59.jar 複製到jre目錄中的/lib/ext

2.編輯/lib/security/java.security 

....
security.provider.1=sun.security.provider.Sun
security.provider.2=sun.security.rsa.SunRsaSign
security.provider.3=sun.security.ec.SunEC
security.provider.4=com.sun.net.ssl.internal.ssl.Provider
security.provider.5=com.sun.crypto.provider.SunJCE
security.provider.6=sun.security.jgss.SunProvider
security.provider.7=com.sun.security.sasl.Provider
security.provider.8=org.jcp.xml.dsig.internal.dom.XMLDSigRI
security.provider.9=sun.security.smartcardio.SunPCSC

#在此加上這句代碼
security.provider.x=org.bouncycastle.jce.provider.BouncyCastleProvider


.....

3.重啓tomcat,解密成功了。。。

 

 

附一份檢測是否支持bouncycastle的代碼。方法:

import org.bouncycastle.jce.provider.BouncyCastleProvider; import javax.crypto.Cipher; import java.security.Security; public class TestB { public static void main(String[] args) throws Exception { Security.addProvider(new BouncyCastleProvider()); System.out.println("Attemptingto get a Cipher and encrypt..."); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding"); System.out.println("OK"); } }

 

若是想用純Js解密也是能夠的,這裏有一篇文章:https://www.cnblogs.com/cai-rd/p/6816849.html

相關文章
相關標籤/搜索