關於“Cannot find any provider supporting AES/ECB/PKCS7Padding”問題的解決方案


出現這個問題的原因是:java自帶的是PKCS5Padding填充,不支持PKCS7Padding填充

參考:https://stackoverflow.com/questions/20770072/aes-cbc-pkcs5padding-vs-aes-cbc-pkcs7padding-with-256-key-size-performance-java

https://crypto.stackexchange.com/questions/9043/what-is-the-difference-between-pkcs5-padding-and-pkcs7-padding

 

需要注意的是AES/CBC/PKCS5Padding 這個參數

AES/CBC/PKCS7Padding 如果是7就不可以,部署在centos7 jdk8 的環境下就會報錯“Cannot find any provider supporting AES/ECB/PKCS7Padding”

 

下面是我微信小程序解密代碼:

import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.spec.InvalidParameterSpecException;

/**
 * java對稱解密的方法
 */
public class AesUtil {

    static {
        //BouncyCastle是一個開源的加解密解決方案,主頁在http://www.bouncycastle.org/
        Security.addProvider(new BouncyCastleProvider());
    }

    /**
     * AES解密
     *
     * @param data           //密文,被加密的數據
     * @param key            //秘鑰
     * @param iv             //偏移量
     * @param encodingFormat //解密后的結果需要進行的編碼
     * @return
     * @throws Exception
     */
    public static String decrypt(String data, String key, String iv, String encodingFormat)
            throws Exception {

        //被加密的數據
        byte[] dataByte = Base64.decodeBase64(data);
        //加密秘鑰
        byte[] keyByte = Base64.decodeBase64(key);
        //偏移量
        byte[] ivByte = Base64.decodeBase64(iv);
        try {
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
            AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
            parameters.init(new IvParameterSpec(ivByte));
            cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化
            byte[] resultByte = cipher.doFinal(dataByte);
            if (null != resultByte && resultByte.length > 0) {
                String result = new String(resultByte, encodingFormat);
                return result;
            }
            return null;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidParameterSpecException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }


}

 

在這段代碼可以運行之前,還有一個問題需要解決。
Java本身限制密鑰的長度最多128位,而AES256需要的密鑰長度是256位,因此需要到Java官網上下載一個Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files。

官方網站提供了JCE無限制權限策略文件的下載:
JDK6的下載地址:
http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html

JDK7的下載地址:
http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html

JDK8的下載地址:
http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html

下載后解壓,可以看到local_policy.jar和US_export_policy.jar以及readme.txt。
如果安裝了JRE,將兩個jar文件放到%JRE_HOME%\lib\security下覆蓋原來文件,記得先備份。
如果安裝了JDK,將兩個jar文件也放到%JDK_HOME%\jre\lib\security下。

只要做了以上兩步,就能正常加解密了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM