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。还请各位如果有遇到相同情况的可以解答一下。

  • 相关阅读:
    win7网络共享原来如此简单,WiFi共享精灵开启半天都弱爆了!
    JQUERY UI Datepicker Demo
    Official online document, install svn server in centOS
    JAVE not work in linux
    AMR 转mp3 失败
    XD, XR, DR 股票
    Linux 下MySql 重置密码
    Difinition Of Done
    Apache, Tomcat, JK Configuration Example
    Linux 安装tomcat
  • 原文地址:https://www.cnblogs.com/xiaoliu66007/p/4687803.html
Copyright © 2011-2022 走看看