2017-02-01 15 views
3

Я не понимаю, почему мой шифр длиннее ожидаемого результата на основе следующих векторов. Я не буду объяснять код, потому что я думаю, что он очень аккуратный и понятный.Что не так с этим шифрованием AES 128?

package mundo; 
import javax.crypto.Cipher; 
import javax.crypto.spec.SecretKeySpec; 
import javax.xml.bind.DatatypeConverter; 

class AESTest { 
    public static void main(String[] args) throws Exception { 
    //each array is a vector case {key, plainText, expectedCipher} 
    String[][] cases = new String[][]{{"00000000000000000000000000000000", "f34481ec3cc627bacd5dc3fb08f273e6","0336763e966d92595a567cc9ce537f5e"}, 
             {"00000000000000000000000000000000", "9798c4640bad75c7c3227db910174e72", "a9a1631bf4996954ebc093957b234589"}, 
             {"2b7e151628aed2a6abf7158809cf4f3c", "6bc1bee22e409f96e93d7e117393172a", "3ad77bb40d7a3660a89ecaf32466ef97"}, 
             {"2b7e151628aed2a6abf7158809cf4f3c", "ae2d8a571e03ac9c9eb76fac45af8e51", "f5d3d58503b9699de785895a96fdbaaf"}}; 
    for(String[] kase : cases) 
    { 
     byte[] theKey = byte2hex(kase[0]); 
     byte[] theMsg = byte2hex(kase[1]); 
     byte[] theExp = byte2hex(kase[2]); 
     Cipher cipher = Cipher.getInstance("AES"); 
     SecretKeySpec keySpec = new SecretKeySpec(theKey, "AES"); 
     cipher.init(Cipher.ENCRYPT_MODE, keySpec); 
     byte[] cryptMsg = cipher.doFinal(theMsg); 
     System.out.println("Key  : "+hex2byte(theKey)); 
     System.out.println("Message : "+hex2byte(theMsg)); 
     System.out.println("Cipher : "+hex2byte(cryptMsg)); 
     System.out.println("Expected: "+hex2byte(theExp) + "\n"); 
    } 
    } 
    public static String hex2byte(byte[] array) { 
     return DatatypeConverter.printHexBinary(array); 
    } 
    public static byte[] byte2hex(String s) { 
     return DatatypeConverter.parseHexBinary(s); 
    } 
} 

Это выход:

Key  : 00000000000000000000000000000000 
Message : F34481EC3CC627BACD5DC3FB08F273E6 
Cipher : 0336763E966D92595A567CC9CE537F5E0143DB63EE66B0CDFF9F69917680151E 
Expected: 0336763E966D92595A567CC9CE537F5E 

Key  : 00000000000000000000000000000000 
Message : 9798C4640BAD75C7C3227DB910174E72 
Cipher : A9A1631BF4996954EBC093957B2345890143DB63EE66B0CDFF9F69917680151E 
Expected: A9A1631BF4996954EBC093957B234589 

Key  : 2B7E151628AED2A6ABF7158809CF4F3C 
Message : 6BC1BEE22E409F96E93D7E117393172A 
Cipher : 3AD77BB40D7A3660A89ECAF32466EF97A254BE88E037DDD9D79FB6411C3F9DF8 
Expected: 3AD77BB40D7A3660A89ECAF32466EF97 

Key  : 2B7E151628AED2A6ABF7158809CF4F3C 
Message : AE2D8A571E03AC9C9EB76FAC45AF8E51 
Cipher : F5D3D58503B9699DE785895A96FDBAAFA254BE88E037DDD9D79FB6411C3F9DF8 
Expected: F5D3D58503B9699DE785895A96FDBAAF 

Почему шифра больше, чем ожидалось. Это надежные 128-битные векторы AES, взятые из справочных книг.

EDIT добавлен в код:

cipher.init(Cipher.DECRYPT_MODE, keySpec); 
byte[] dcrypMsg = cipher.doFinal(cryptMsg); 
System.out.println("Decrypted: " + byte2hex(dcrypMsg) + "\n"); 

дешифрование является правильным, но я до сих пор не могу понять ...

Key  : 2B7E151628AED2A6ABF7158809CF4F3C 
Message : AE2D8A571E03AC9C9EB76FAC45AF8E51 
Cipher : F5D3D58503B9699DE785895A96FDBAAFA254BE88E037DDD9D79FB6411C3F9DF8 
Expected: F5D3D58503B9699DE785895A96FDBAAF 
Decrypted: AE2D8A571E03AC9C9EB76FAC45AF8E51 

ответ

4

, пожалуйста, используйте Cipher.getInstance("AES/ECB/NoPadding"); , чтобы убедиться, ваш вклад делает не заполняйте. Затем я получаю ожидаемый результат для всех ваших тестовых случаев.

В соответствии с https://docs.oracle.com/javase/8/docs/api/javax/crypto/Cipher.html:

Преобразование имеет вид:

«алгоритма/режима/дополнения» или «алгоритм» (в последнем случае, поставщика конкретных значений по умолчанию для режим и схема заполнения - ).

Вы не знаете, какое дополнение используется, если вы не указали его. Я предполагаю, что ваши входные данные дополняются, что означает, что что-то добавлено к вашему вводу, чтобы заполнить его, например, у вас есть набор полных блоков блочного кода вашего шифра. Ваша длина ввода уже делится блоками, поэтому добавляется полный блок, в результате чего сообщение имеет удвоенную ожидаемую длину.

2

Если вы не укажете режим цепочки шифрования и алгоритм заполнения, тогда JDK примет значения по умолчанию. Крипто спецификация советует им не уточняя:

Рекомендуется использовать преобразование, которое полностью определяет алгоритм, режим, и отступы. Не делая этого, поставщик будет использовать по умолчанию. Например, поставщики SunJCE и SunPKCS11 используют ECB как режим по умолчанию, а PKCS5Padding - как дополнение по умолчанию для многих симметричных шифров . http://docs.oracle.com/javase/7/docs/technotes/guides/security/crypto/CryptoSpec.html#trans

Чтобы получить желаемый результат, необходимо использовать режим Electronic Cookbook (ECB) - так не цепь блоков - и без полей:

Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding"); 

 Смежные вопросы

  • Нет связанных вопросов^_^