Hematemesis records the pits encountered by the WeChat applet authorized to obtain Unionid and AES decryption of user data

background

The company's applet was launched, and it was found that some systems could not get the UniondID of some users. But the test before going live is normal.

pit 1

After investigation, it was found that some users could not get the unionid through the following interface

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

Read https://developers.weixin.qq.com/miniprogram/dev/api/uinionID.html  to learn that users who have never been authorized in the associated official account or applet will not directly return the unionid. To get the unionid of these users, the following 3 data are required

1. The session_key returned by https://api.weixin.qq.com/sns/jscode2session

2. The encryptedData and iv returned by wx.getUserInfo and the user agrees

Use the following code to decrypt the user's information



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;
    }


}  

 

Pit 2, the place where the blood really vomits

It is no problem to use the above method to test on my local machine, but there is another problem after deploying the project on Linux

An exception is thrown when decrypting:

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

When I look back at the code, to achieve padding with PKCS7Padding on the java side, the bouncycastle component needs to be used to implement it, and it is indeed set in the decryption code. And the machine can also be decrypted, the jdk on the machine and linux are the 1.8 version downloaded from the official website, why not on Linux?

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

bouncycastle is also referenced in maven


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

 

If the code problem is ruled out, it is obviously an environmental problem. Using Security.addProvider(new BouncyCastleProvider()); on linux does not work. . .

 

There is no other way, you can only manually change the jre. Proceed as follows

1. Copy bcprov-jdk15on-1.59.jar to /lib/ext in the jre directory

2. Edit /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. Restart tomcat, the decryption is successful. . .

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324938545&siteId=291194637