zoukankan      html  css  js  c++  java
  • java PKCS7Padding 加密Cannot find any provider supporting AES/CBC/PKCS7Padding 解决办法

    在java中用aes256进行加密,但是发现java里面不能使用PKCS7Padding,而java中自带的是PKCS5Padding填充,那解决办法是,通过BouncyCastle组件来让java里面支持PKCS7Padding填充。

    説辣么多不如上代码:

    public class AESUtil {

    /**
    * Encodes a String in AES-256 with a given key
    *
    * @param context
    * @param password
    * @param text
    * @return String Base64 and AES encoded String
    */
    public static String encode(String keyString, String stringToEncode) throws NullPointerException {
    if (keyString.length() == 0 || keyString == null) {
    throw new NullPointerException("Please give Password");
    }

    if (stringToEncode.length() == 0 || stringToEncode == null) {
    throw new NullPointerException("Please give text");
    }

    try {
    SecretKeySpec skeySpec = getKey(keyString);
    byte[] clearText = stringToEncode.getBytes("UTF8");

    // IMPORTANT TO GET SAME RESULTS ON iOS and ANDROID
    final byte[] iv = new byte[16];
    Arrays.fill(iv, (byte) 0x00);
    IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

    /**
    * 这个地方调用BouncyCastleProvider
    *让java支持PKCS7Padding
    */
    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    // Cipher is not thread safe
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivParameterSpec);

    String encrypedValue = Base64.encodeToString(cipher.doFinal(clearText), Base64.DEFAULT);
    // Log.d("jacek", "Encrypted: " + stringToEncode + " -> " + encrypedValue);
    return encrypedValue;

    } catch (InvalidKeyException e) {
    e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
    e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
    e.printStackTrace();
    } catch (BadPaddingException e) {
    e.printStackTrace();
    } catch (NoSuchPaddingException e) {
    e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
    e.printStackTrace();
    } catch (InvalidAlgorithmParameterException e) {
    e.printStackTrace();
    }
    return "";
    }

    /**
    * Decodes a String using AES-256 and Base64
    *
    * @param context
    * @param password
    * @param text
    * @return desoded String
    */
    public static String decode(String password, String text) throws NullPointerException {

    if (password.length() == 0 || password == null) {
    throw new NullPointerException("Please give Password");
    }

    if (text.length() == 0 || text == null) {
    throw new NullPointerException("Please give text");
    }

    try {
    SecretKey key = getKey(password);

    // IMPORTANT TO GET SAME RESULTS ON iOS and ANDROID
    final byte[] iv = new byte[16];
    Arrays.fill(iv, (byte) 0x00);
    IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

    byte[] encrypedPwdBytes = Base64.decode(text, Base64.DEFAULT);
    // cipher is not thread safe

    /**
    * 这个地方调用BouncyCastleProvider
    *让java支持PKCS7Padding
    */
    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
    cipher.init(Cipher.DECRYPT_MODE, key, ivParameterSpec);
    byte[] decrypedValueBytes = (cipher.doFinal(encrypedPwdBytes));

    String decrypedValue = new String(decrypedValueBytes);
    //Log.d(LOG_TAG, "Decrypted: " + text + " -> " + decrypedValue);
    return decrypedValue;

    } catch (InvalidKeyException e) {
    e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
    e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
    e.printStackTrace();
    } catch (BadPaddingException e) {
    e.printStackTrace();
    } catch (NoSuchPaddingException e) {
    e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
    e.printStackTrace();
    } catch (InvalidAlgorithmParameterException e) {
    e.printStackTrace();
    }
    return "";
    }

    /**
    * Generates a SecretKeySpec for given password
    *
    * @param password
    * @return SecretKeySpec
    * @throws UnsupportedEncodingException
    */
    private static SecretKeySpec getKey(String password) throws UnsupportedEncodingException {

    // You can change it to 128 if you wish
    int keyLength = 256;
    byte[] keyBytes = new byte[keyLength / 8];
    // explicitly fill with zeros
    Arrays.fill(keyBytes, (byte) 0x0);

    // if password is shorter then key length, it will be zero-padded
    // to key length
    byte[] passwordBytes = password.getBytes("UTF-8");
    int length = passwordBytes.length < keyBytes.length ? passwordBytes.length : keyBytes.length;
    System.arraycopy(passwordBytes, 0, keyBytes, 0, length);
    SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
    return key;
    }

    public static void main(String args[])
    {
    long startTime = System.currentTimeMillis();
    String encodeStr = AESUtil.encode("1234", "你要去哪儿test123");
    System.out.println("encoder:"+encodeStr);
    String decodeStr = AESUtil.decode("1234",encodeStr);
    System.out.println("decoder:"+decodeStr);


    }
    }

    BouncyCastle组件相关jar包bcprov-jdk15on-152.jar的下载地址:http://www.bouncycastle.org

     默认 Java 中仅支持 128 位密钥,当使用 256 位密钥的时候,会报告密钥长度错误 你需要下载一个支持更长密钥的包。这个包叫做

    Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 8

    ,可以从这里下载,下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html。下好了zip文件以后,把里面的两个jar包(local_policy.jar,US_export_policy.jar)替换掉jdk的security文件夹中相应的jar包就OK啦。

    但是我确实遇到一个比较奇怪的问题,我在android上面调用PKCS7Padding 是没有问题的,但是在java写的服务端就有问题了。不知道为什么,我用的jdk都是1.8.0的jdk。还请各位如果有遇到相同情况的可以解答一下。

  • 相关阅读:
    带结点与不带结点用头插法和尾插法创建单链表
    高中数学教资面试记录
    学习爬虫——test1——模拟浏览器去访问网站
    解决centos虚拟机中使用virt-manager创建虚拟机遇到的镜像导入问题
    pycharm更改背景颜色
    控制函数调用的流程
    简单的获取list的下标
    种一棵树的时间,不是以前,也不是未来的某一天,而是现在。
    将八位教师随机分配到三个办公室——python
    使用tomcat部署idea项目方法(1)
  • 原文地址:https://www.cnblogs.com/xiaoliu66007/p/4687803.html
Copyright © 2011-2022 走看看