java文件加解密,java.security.InvalidKeyException: Illegal key size or default parameters问题解决

使用AES加密时,当密钥大于128时,代码会抛出java.security.InvalidKeyException: Illegal key size or default parameters。网上大部分的解决方法都是下载相关的jar包,覆盖掉${java_home}/jre/lib/security/ 下面的local_policy.jar和US_export_policy.jar来解除这种限制。但有时候,在生产环境中不能或不方便进行这种覆盖操作,这时候可以在加解密代码中加上下列代码去掉这种限制:

//使其支持256位秘钥
static {
    Field field = null;
    try {
        field = Class.forName("javax.crypto.JceSecurity").getDeclaredField("isRestricted");
        field.setAccessible(true);
        Field modifiersField = Field.class.getDeclaredField("modifiers");
        modifiersField.setAccessible(true);
        modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
        field.set(null, java.lang.Boolean.FALSE);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

顺便提供一个文件加解密的类FileAesEncryptUtil.java

package com.learn;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.security.GeneralSecurityException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

public class FileAesEncryptUtil {

    //可修改成配置,SECRET根据实际修改
    private final static String SECRET = "JXU4RkQ5JXU5MUNDJXU2NjJGJXU4OTgxJXU1MkEwJXU1QkM2JXU3Njg0JXU1MTg1JXU1QkI5JXVGRjAx";
    private final static String AES = "AES";
    private final static String AESArgs = "AES/ECB/PKCS5Padding";

    //使其支持256位秘钥
    static {
        Field field = null;
        try {
            field = Class.forName("javax.crypto.JceSecurity").getDeclaredField("isRestricted");
            field.setAccessible(true);
            Field modifiersField = Field.class.getDeclaredField("modifiers");
            modifiersField.setAccessible(true);
            modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
            field.set(null, java.lang.Boolean.FALSE);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //生成256位的秘钥
    private static SecretKey generateAesSecretKey() {
        try {
            KeyGenerator keygen = KeyGenerator.getInstance(AES);
            SecureRandom sha1PANG = SecureRandom.getInstance("SHA1PRNG");
            sha1PANG.setSeed(SECRET.getBytes());
            keygen.init(256, sha1PANG);
            return keygen.generateKey();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }

    //加密解密流文件
    private static void crypt(InputStream in, OutputStream out, Cipher cipher) throws IOException, GeneralSecurityException {
        int blockSize = cipher.getBlockSize() * 1000;
        int outputSize = cipher.getOutputSize(blockSize);
        byte[] inBytes = new byte[blockSize];
        byte[] outBytes = new byte[outputSize];
        int inLength = 0;
        boolean more = true;
        while (more) {
            inLength = in.read(inBytes);
            if (inLength == blockSize) {
                int outLength = cipher.update(inBytes, 0, blockSize, outBytes);
                out.write(outBytes, 0, outLength);
            } else {
                more = false;
            }
        }
        if (inLength > 0)
            outBytes = cipher.doFinal(inBytes, 0, inLength);
        else
            outBytes = cipher.doFinal();
        out.write(outBytes);
    }

    //加密
    public static void encodeFile(File srcFile, File destFile) throws IOException, GeneralSecurityException {
        // 获取cipher对象  用于加密解密
        Key key = generateAesSecretKey();
        Cipher cipher = Cipher.getInstance(AESArgs);
        cipher.init(Cipher.ENCRYPT_MODE, key);    // 加密是为ENCRYPT_MODE
        InputStream is = new FileInputStream(srcFile);
        OutputStream os = new FileOutputStream(destFile);
        crypt(is, os, cipher);
        os.close();
        is.close();
    }

    //解密
    public static void decodeAES(File srcFile, File destFile) throws IOException, GeneralSecurityException {
        // 获取cipher对象  用于加密解密
        Key key = generateAesSecretKey();
        Cipher cipher = Cipher.getInstance(AESArgs);
        cipher.init(Cipher.DECRYPT_MODE, key);    // 解密是为DECRYPT_MODE
        InputStream is = new FileInputStream(srcFile);
        OutputStream os = new FileOutputStream(destFile);
        crypt(is, os, cipher);
        os.close();
        is.close();
    }

}

测试

package com.learn;

import java.io.File;
public class App 
{
    public static void main( String[] args )
    {
       File src= new File("/test.txt");
       File encode= new File("/encode.txt");
       File decode=new File("/decode.txt");
        try {
            FileAesEncryptUtil.encodeFile(src,encode);
            FileAesEncryptUtil.decodeAES(encode,decode);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

结果
结果

猜你喜欢

转载自blog.csdn.net/YINLINNEVERG/article/details/82492135