当前位置: 首页 > 知识库问答 >
问题:

初始化cipher:Java.security.InvalidKeyException时Java加密引发异常:非法密钥大小

葛烨
2023-03-14

我正在尝试使用“AES/GCM/Nopadding”加密一个简单的测试“Sometext”。
我有一个main方法,首先传递一个字符串作为参数,该参数应该被加密。加密的文本将出现在控制台上。然后,调用解密(通过传递加密文本)来检查解密是否正常,即解密后是否返回相同的文本。我正在调用主类,但它在我的getcipher()自定义方法中失败,出现异常:

Exception in thread "main" my.package.EncryptionException: java.security.InvalidKeyException: Illegal key size
        at my.package.Encryptor.encrypt(Encryptor.java:76)
        at my.package.Encryptor.encrypt(Encryptor.java:61)
        at my.package.Encryptor.main(Encryptor.java:151)
Caused by: java.security.InvalidKeyException: Illegal key size
        at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1039)
        at javax.crypto.Cipher.implInit(Cipher.java:805)
        at javax.crypto.Cipher.chooseProvider(Cipher.java:864)
        at javax.crypto.Cipher.init(Cipher.java:1396)
        at javax.crypto.Cipher.init(Cipher.java:1327)
        at my.package.Encryptor.getCipher(Encryptor.java:134)
        at my.package.Encryptor.encrypt(Encryptor.java:69)
        ... 2 more

我不确定为什么这个非法密钥大小给出错误。我的密钥“secretkey”在16个字符内。
下面是代码:

public class Encryptor {

    private static final String ALGORITHM_AES256 = "AES/GCM/NoPadding";
    private static final int IV_LEN = 16;
    private static final int KEY_LEN = 32;
    private final SecureRandom random;
    private final byte[] inputKey;
    private final SecretKeySpec secretKeySpec;
    private final Cipher cipher;

    Encryptor() throws EncryptionException 
    {
        String secretKey = "SecREtKeY";
        byte[] key = secretKey.getBytes(StandardCharsets.UTF_8);
        if (key == null) {
            throw new EncryptionException("Null Key");
        }

        inputKey = new byte[key.length];
        System.arraycopy(key, 0, inputKey, 0, inputKey.length);

        byte[] aesKey = trimKey(key);
        System.out.println("aesKey.length: "+aesKey.length);

        try
        {
            random = SecureRandom.getInstance("SHA1PRNG");
            this.secretKeySpec = new SecretKeySpec(aesKey, "AES");
            this.cipher = Cipher.getInstance(ALGORITHM_AES256);
        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
            throw new EncryptionException(e);
        }
    }

    /*
     * Encrypts plaint text. Returns Encrypted String.
     */
    String encrypt(String plaintext) throws EncryptionException
    {
        return encrypt(plaintext.getBytes(StandardCharsets.UTF_8));
    }

    String encrypt(byte[] plaintext) throws EncryptionException
    {
        try 
        {
            byte[] iv = getRandom(IV_LEN);
            Cipher msgcipher = getCipher(Cipher.ENCRYPT_MODE, iv);
            byte[] encryptedTextBytes = msgcipher.doFinal(plaintext);
            byte[] payload = concat(iv, encryptedTextBytes);

            return Base64.getEncoder().encodeToString(payload);
        } 
        catch (BadPaddingException | InvalidKeyException | IllegalBlockSizeException | InvalidAlgorithmParameterException e){
            throw new EncryptionException(e);
        }
    }

    /*
     * Decrypts plaint text. Returns decrypted String.
     */
    String decrypt(String ciphertext) throws EncryptionException 
    {
        return decrypt(Base64.getDecoder().decode(ciphertext));
    }

    String decrypt(byte[] cipherBytes) throws EncryptionException 
    {
        byte[] iv = Arrays.copyOf(cipherBytes, IV_LEN);

        byte[] cipherText = Arrays.copyOfRange(cipherBytes, IV_LEN, cipherBytes.length);
        try {
            Cipher cipher = getCipher(Cipher.DECRYPT_MODE, iv);
            byte[] decrypt = cipher.doFinal(cipherText);
            return new String(decrypt, StandardCharsets.UTF_8);
        } catch (BadPaddingException | InvalidKeyException | IllegalBlockSizeException | InvalidAlgorithmParameterException e) {
            throw new EncryptionException(e);
        }
    }


    private byte[] trimKey(byte[] key)
    {
        byte[] outkey = new byte[KEY_LEN];

        if(key.length >= KEY_LEN) {
            System.arraycopy(key, key.length - KEY_LEN, outkey, 0, KEY_LEN);
        } 
        else {
            System.arraycopy(key, 0, outkey, 0, key.length);
        }

        return outkey;
    }

    private byte[] getRandom(int size) 
    {
        byte[] data = new byte[size];
        random.nextBytes(data);
        return data;
    }

    private byte[] concat(byte[] first, byte[] second) 
    {
        byte[] result = Arrays.copyOf(first, first.length + second.length);
        System.arraycopy(second, 0, result, first.length, second.length);
        return result;
    }

    private Cipher getCipher(int encryptMode, byte[] iv) throws InvalidKeyException, InvalidAlgorithmParameterException 
    {
        GCMParameterSpec gcmSpec = new GCMParameterSpec(IV_LEN * 8, iv);
        cipher.init(encryptMode, getSecretKeySpec(), gcmSpec);
        return cipher;
    }

    private SecretKeySpec getSecretKeySpec() {
        return secretKeySpec;
    }



    public static void main(String[] args) throws Exception 
    {
        if(args.length == 1) {
            String plainText = args[0];

            Encryptor aes = new Encryptor();

            String encryptedString = aes.encrypt(plainText);
            System.out.println(plainText + ":" + encryptedString);

            String decryptedString = aes.decrypt(encryptedString);
            System.out.println(encryptedString+":"+decryptedString);
        } 
        else {
            System.out.println("USAGE: java my.package.Encryptor [text to encrypt]");
        }
    }
}  

知道为什么我会得到这个错误吗?

共有1个答案

屈星腾
2023-03-14

Java.security.InvalidKeyException:非法密钥大小表示您尚未安装JCE(Java加密扩展)。AES256需要它

对于Java8,您可以在这里下载:http://www.oracle.com/technetwork/Java/javase/downloads/jce8-download-2133166.html

 类似资料:
  • 问题内容: 我的测试可以在开发的MacBook Pro上很好地运行,但是无法在持续集成的TeamCity服务器中运行。 错误如下: java.security.InvalidKeyException: Illegal key size at javax.crypto.Cipher.a(DashoA13..) at javax.crypto.Cipher.init(DashoA13 ..) at j

  • 我目前正在用java编写一个加密消息传递服务,我使用的是bouncycastle PGP库。我编写了一个生成密钥对的测试程序,并对消息进行加密/解密。这已经工作了一段时间,但它最近在解密阶段停止了,给了我一个InvalidKeyException。 我做了一些研究,下载了JCE.jar文件,并将它们导入到我的项目中(通过Eclipse Project->Properties->add extern

  • 下面是我的加密方法(值是一个输入参数): 下面是我的解密方法(值是一个输入参数): 我有个例外: 我读过不同的主题,所以我发现,当没有填充和有另一种密码模式时,就会发生这种异常。那么,怎么了?

  • 问题内容: 这是我的代码,用于使用密钥库将任意文本保存为密钥库中的密钥,如何获取“密钥库未初始化错误”,如何初始化密钥库? 问题答案: 密钥库 必须 初始化,因此您 必须 调用该方法。在您的情况下,您可以例如调用:

  • 也许你能帮我。非常感谢!

  • 我正在努力解决这个问题。所以我几乎编写了整个代码,但问题是我无法初始化监视器(我编写了伪代码,我用c重新编写),所以我无法测试程序。谁能帮我说说监视器/互斥体初始化有什么问题吗? 我在第18行得到错误,它是这样的:error:'intpthread\u mutex\u init'被重新声明为不同类型的符号 将其更改为int pthread_mutex_init( 通过添加int pthread_m