如何解决无效的AES密钥长度?

我正在研究 项目(遵循Struts 2)

每当我输入密码和纯文本时,都会收到“无效的AES密钥长度”错误。

package com.anoncrypt.services;

import java.security.Key;

import javax.crypto.Cipher;

import javax.crypto.spec.SecretKeySpec;

import sun.misc.BASE64Decoder;

import sun.misc.BASE64Encoder;

public class SymAES

{

private static final String ALGORITHM = "AES";

private static byte[] keyValue= new byte[] { 'T', 'h', 'i', 's', 'I', 's', 'A', 'S', 'e', 'c', 'r', 'e', 't', 'K', 'e', 'y' };

public String encode(String valueToEnc) throws Exception {

Key key = new SecretKeySpec(keyValue, ALGORITHM);

Cipher c = Cipher.getInstance(ALGORITHM);

c.init(Cipher.ENCRYPT_MODE, key);

byte[] encValue = c.doFinal(valueToEnc.getBytes());

String encryptedValue = new BASE64Encoder().encode(encValue);

return encryptedValue;

}

public String decode(String encryptedValue) throws Exception {

Key key = new SecretKeySpec(keyValue, ALGORITHM);

Cipher c = Cipher.getInstance(ALGORITHM);

c.init(Cipher.DECRYPT_MODE, key);

byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedValue);

byte[] decValue = c.doFinal(decordedValue);

String decryptedValue = new String(decValue);

return decryptedValue;

}

public void start(String passcode)throws Exception

{

keyValue = passcode.getBytes();

}

}


这是错误

java.security.InvalidKeyException: Invalid AES key length: 6 bytes

com.sun.crypto.provider.AESCrypt.init(AESCrypt.java:87)

com.sun.crypto.provider.ElectronicCodeBook.init(ElectronicCodeBook.java:93)

com.sun.crypto.provider.CipherCore.init(CipherCore.java:582)

com.sun.crypto.provider.CipherCore.init(CipherCore.java:458)

com.sun.crypto.provider.AESCipher.engineInit(AESCipher.java:307)

javax.crypto.Cipher.implInit(Cipher.java:797)

javax.crypto.Cipher.chooseProvider(Cipher.java:859)

javax.crypto.Cipher.init(Cipher.java:1229)

javax.crypto.Cipher.init(Cipher.java:1166)

com.anoncrypt.services.SymAES.encode(SymAES.java:35)

com.anoncrypt.actions.SymEncrypt.execute(SymEncrypt.java:24)

回答:

回答:

    • SecretKeySpec需要键,而不是密码。见下文

  1. 这可能是由于策略限制导致无法使用32个字节的密钥。看到其他答案

回答:

问题是数字1:您要传递密码而不是密钥。

AES仅支持16、24或32字节的密钥大小。您要么需要提供准确的金额,要么从键入的内容中得出密钥。

有多种方法可以从密码短语中获取密钥。Java为此提供了PBKDF2实现。

我使用了埃里克森的答案来描绘出完整的图片(仅加密,因为解密是相似的,但包括分割密文):

SecureRandom random = new SecureRandom();

byte[] salt = new byte[16];

random.nextBytes(salt);

KeySpec spec = new PBEKeySpec("password".toCharArray(), salt, 65536, 256); // AES-256

SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");

byte[] key = f.generateSecret(spec).getEncoded();

SecretKeySpec keySpec = new SecretKeySpec(key, "AES");

byte[] ivBytes = new byte[16];

random.nextBytes(ivBytes);

IvParameterSpec iv = new IvParameterSpec(ivBytes);

Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");

c.init(Cipher.ENCRYPT_MODE, keySpec, iv);

byte[] encValue = c.doFinal(valueToEnc.getBytes());

byte[] finalCiphertext = new byte[encValue.length+2*16];

System.arraycopy(ivBytes, 0, finalCiphertext, 0, 16);

System.arraycopy(salt, 0, finalCiphertext, 16, 16);

System.arraycopy(encValue, 0, finalCiphertext, 32, encValue.length);

return finalCiphertext;


其他注意事项:

  • 始终使用完全限定的密码名称。AES在这种情况下不适用,因为不同的JVM / JCE提供程序可能对操作和填充模式使用不同的默认值。使用AES/CBC/PKCS5Padding。不要使用ECB模式,因为它在语义上并不安全。
  • 如果您不使用ECB模式,则需要将IV和密文一起发送。这通常是通过在IV前面加上密文字节数组来完成的。IV是自动为您创建的,您可以通过它获得cipherInstance.getIV()
  • 每当您发送邮件时,都需要确保该邮件在发送过程中没有被更改。很难用MAC正确实现加密。我建议您使用CCM或GCM之类的身份验证模式。

以上是 如何解决无效的AES密钥长度? 的全部内容, 来源链接: utcz.com/qa/409557.html

回到顶部