Pourquoi le texte chiffré de 32 octets est-il long lors du chiffrement de 16 octets avec AES?
Je utiliser le chiffrement algorithme AES, quand j'ai chiffrer 16 octets(un bloc) le résultat est de 32 octets.
Est-ce ok?
Mon code source que j'ai utilisé est:
package net.sf.andhsli.hotspotlogin;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
/**
* Usage:
* <pre>
* String crypto = SimpleCrypto.encrypt(masterpassword, cleartext)
* ...
* String cleartext = SimpleCrypto.decrypt(masterpassword, crypto)
* </pre>
* @author ferenc.hechler
*/
public class SimpleCrypto {
public static String encrypt(String seed, String cleartext) throws Exception {
byte[] rawKey = getRawKey(seed.getBytes());
byte[] result = encrypt(rawKey, cleartext.getBytes());
return toHex(result);
}
public static String decrypt(String seed, String encrypted) throws Exception {
byte[] rawKey = getRawKey(seed.getBytes());
byte[] enc = toByte(encrypted);
byte[] result = decrypt(rawKey, enc);
return new String(result);
}
private static byte[] getRawKey(byte[] seed) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed);
kgen.init(128, sr); //192 and 256 bits may not be available
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
return raw;
}
private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(clear);
return encrypted;
}
private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(encrypted);
return decrypted;
}
public static String toHex(String txt) {
return toHex(txt.getBytes());
}
public static String fromHex(String hex) {
return new String(toByte(hex));
}
public static byte[] toByte(String hexString) {
int len = hexString.length()/2;
byte[] result = new byte[len];
for (int i = 0; i < len; i++)
result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue();
return result;
}
public static String toHex(byte[] buf) {
if (buf == null)
return "";
StringBuffer result = new StringBuffer(2*buf.length);
for (int i = 0; i < buf.length; i++) {
appendHex(result, buf[i]);
}
return result.toString();
}
private final static String HEX = "0123456789ABCDEF";
private static void appendHex(StringBuffer sb, byte b) {
sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f));
}
}
source d'informationauteur ebra
Vous devez vous connecter pour publier un commentaire.
Si vous regardez la spécification de l'article 5 ensuite, vous pouvez voir que l'entrée, la sortie et l'état sont tous de 128 bits. La seule chose qui varie, c'est la taille de la clé: 128, 196 ou 256 bits. Afin de chiffrer un 16 octets d'entrée de l'état aura un rendement de 16 octets de sortie de l'état.
Êtes-vous sûr de ne pas le mélanger avec de la longueur, en notation hexadécimale ou similaires? Si il est en notation hexadécimale, puis c'est correct, parce que pour chaque octet de deux caractères sont nécessaires pour la représenter:
00-FF
(pour la gamme0-255
).Une autre façon, vous pouvez tester si le cryptage est correcte est en fait l'équivalent de déchiffrement, de voir si elle correspond au texte en clair de la chaîne d'entrée.
De toute façon, il fait la bonne chose. Voici un test:
Ce qui donne:
AES par défaut de la BCE mode de cryptage avec PKCS#7 compatible mode de remplissage (pour tous les fournisseurs de observée jusqu'à présent). La BCE et le chiffrement en mode CBC exiger remplissage si l'entrée n'est pas exactement un multiple de la taille des blocs de taille, avec 16 étant la taille du bloc de l'AES en octets.
Malheureusement, il pourrait y avoir aucun moyen pour le unpadding mécanisme de distinguer entre le rembourrage et de données; les données lui-même peut représenter valide rembourrage. Donc, pour 16 octets d'entrée, vous obtiendrez un autre de 16 octets de remplissage. Rembourrage modes qui sont déterministes tels que PKCS#7 toujours pad avec 1 pour [taille de bloc] octets.
Si vous regardez
int output = cipher.getOutputSize(16);
vous recevrez 32 octets. Utilisation"AES/ECB/NoPadding"
au cours de déchiffrer pour voir les octets de remplissage (par exemple,4D61617274656E20426F64657765732110101010101010101010101010101010
).Vous êtes mieux quand vous de bien spécifier l'algorithme (
"AES/CBC/PKCS5Padding"
est utilisé normalement). Sinon, vous devrez garder de deviner quel mode est utilisé.Notez que l'utilisation de la BCE mode n'est pas sûr que l'attaquant peut récupérer des informations à partir du texte chiffré. Identique blocs de texte en clair pour encoder les mêmes blocs de texte chiffré.