Класс шифрования из пакета javax.crypto не работает должным образом с использованием алгоритма DES
Вот мой код:
public byte[] encrypt(byte[] key, byte[] pText) throws Exception
{
System.out.println( DatatypeConverter.printHexBinary(key)); // Outputs: 3FBB589A6A941D01
System.out.println( DatatypeConverter.printHexBinary(pText)); // Outputs: 92F3BD61F852727E
Cipher ciph = Cipher.getInstance("DES");
SecretKey blah = new SecretKeySpec(key, 0, key.length, "DES");
ciph.init(Cipher.ENCRYPT_MODE, blah);
byte[] test = ciph.doFinal(pText);
System.out.println( DatatypeConverter.printHexBinary(test)); // Outputs: 4799F8A1C0A427E17E2B19DD22064444
return test;
}
Пара вещей, в которых я не уверен:
- Я добавил ключ с 01, поэтому вывод в первой строке заканчивается 01. Я попытался заполнить его 0, но это тоже не сработало. И требуемая длина составляет 8 байтов. Так что не уверен, правильно ли я это сделал.
- Я не совсем уверен, что означает смещение в конструкторе SecretKey (2-й аргумент). Я предполагаю, что это должно быть 0.
- Мой главный вопрос: почему тест (cipherText) 16 байтов? Согласно http://www.facweb.iitkgp.ernet.in/~sourav/DES.pdf стр. 13 это должно быть только 8 байт.
Я также знаю, что мой код не работает, потому что я знаю, каким должен быть окончательный зашифрованный вывод.
1 ответ
Вы не указываете режим и заполнение для шифра в вызове getInstance()
, поэтому провайдер выберет параметры по умолчанию. Ваш провайдер по умолчанию использует "PKCS5Padding", поэтому он добавляет 8 байтов со значением 0x08 к вашему простому тексту перед выполнением шифрования DES.
Чтобы избежать поведения платформы, очень важно указать полное преобразование при создании Cipher
Экземпляр: алгоритм, режим и заполнение. Если вы не хотите заполнять, скажите так:
Cipher ciph = Cipher.getInstance("DES/ECB/NoPadding");
SecretKey blah = new SecretKeySpec(key, "DES");
Почему ты набил свой ключ? Почему ваш ключ не был длиной 8 байт, чтобы начать? Если первые 7 байтов предназначены для использования в качестве фактического ключа, и в них отсутствуют биты четности, вы не можете просто шлепнуть байт в конце; вам нужно расширить ключ до восьми байтов, добавив один бит четности к каждому 7-битному фрагменту.
Если вы используете ключ с контролем четности, 3EDCD613A754513B
и без заполнения, зашифрованный текст C094C47D7F89E219
, Это то, что вы ожидаете?