Класс шифрования из пакета 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;
}

Пара вещей, в которых я не уверен:

  1. Я добавил ключ с 01, поэтому вывод в первой строке заканчивается 01. Я попытался заполнить его 0, но это тоже не сработало. И требуемая длина составляет 8 байтов. Так что не уверен, правильно ли я это сделал.
  2. Я не совсем уверен, что означает смещение в конструкторе SecretKey (2-й аргумент). Я предполагаю, что это должно быть 0.
  3. Мой главный вопрос: почему тест (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, Это то, что вы ожидаете?

Другие вопросы по тегам