web-dev-qa-db-fra.com

Obtention de l'exception Java.security.InvalidKeyException: longueur de clé AES non valide: 29 octets?

Lors de l'exécution sous le programme, j'obtiens cette exception. Vous ne savez pas quel est le problème, car AES autorise la clé 128 -256 bits?

 Exception in thread "main" Java.security.InvalidKeyException: Invalid AES key length: 29 bytes
at com.Sun.crypto.provider.AESCipher.engineGetKeySize(DashoA13*..)
at javax.crypto.Cipher.b(DashoA13*..)

Obtention d'une exception à la ligne 20

Voici le programme

 import Java.security.Key;

 import javax.crypto.Cipher;
 import javax.crypto.spec.SecretKeySpec;

 import Sun.misc.BASE64Decoder;
 import Sun.misc.BASE64Encoder;

 public class AESEncryptionDecryptionTest {

   private static final String ALGORITHM       = "AES";
   private static final String myEncryptionKey = "ThisIsSecurityKey";
   private static final String UNICODE_FORMAT  = "UTF8";

   public static String encrypt(String valueToEnc) throws Exception {
 Key key = generateKey();
 Cipher c = Cipher.getInstance(ALGORITHM);
 c.init(Cipher.ENCRYPT_MODE, key);  //////////LINE 20
 byte[] encValue = c.doFinal(valueToEnc.getBytes());
 String encryptedValue = new BASE64Encoder().encode(encValue);
 return encryptedValue;
   }

public static String decrypt(String encryptedValue) throws Exception {
Key key = generateKey();
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;
}

private static Key generateKey() throws Exception {
byte[] keyAsBytes;
keyAsBytes = myEncryptionKey.getBytes(UNICODE_FORMAT);
Key key = new SecretKeySpec(keyAsBytes, ALGORITHM);
return key;
}

public static void main(String[] args) throws Exception {

String value = "password1";
String valueEnc = AESEncryptionDecryptionTest.encrypt(value);
String valueDec = AESEncryptionDecryptionTest.decrypt(valueEnc);

System.out.println("Plain Text : " + value);
System.out.println("Encrypted : " + valueEnc);
System.out.println("Decrypted : " + valueDec);
}

}
12
M Sach

AES autorise une longueur de clé de 128, 192 ou 256 bits. C'est 16, 24 ou 32 octets. Essayez de prendre uniquement les 16 premiers octets de votre mEncryptionKey comme keyAsBytes.

Modifier:
Un après-coup me vint à l'esprit. Une habitude que j'ai prise, et que je recommande, est de prendre un SHA hachage d'un mot de passe/phrase de passe, et de l'utiliser comme octets source de votre clé. Prendre un hachage garantit la clé les données auront la taille correcte, quelle que soit la longueur du mot de passe/phrase de passe. Votre implémentation actuelle de l'utilisation des octets de chaîne a deux problèmes;

  • Cela brisera votre génération de clés si quelqu'un utilise un mot de passe court.
  • Deux mots de passe différents pour lesquels les 16 premiers octets sont identiques créeront la même clé.

Ces deux problèmes sont éliminés en utilisant un hachage.

Jetez un œil à la méthode buildKey() dans cette classe; https://github.com/qwerky/DataVault/blob/master/src/qwerky/tools/datavault/DataVault.Java

30
Qwerky

La clé utilise l'aléatoire comme entrée, mais il existe des exigences stiill pour la façon dont elle est composée. Le constructeur SecretKeySpec que vous avez utilisé sert à charger une clé déjà générée en mémoire. Utilisez plutôt KeyGenerator .

KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM);
kg.init(128);
SecretKey k = kg.generateKey();

Notez également que l'AES-128 est actuellement considéré comme plus faible que l'AES-256. Ce n'est probablement pas radicalement différent, mais les avantages d'une taille de clé plus longue peuvent être compensés par des simplifications ailleurs (moins de tours).

1
John Watts