Создать ключ DES из 56-битной двоичной строки - PullRequest
8 голосов
/ 13 февраля 2011

У меня есть 56-битная двоичная строка, которую я хочу использовать в качестве секретного ключа для шифрования DES.

Я нашел следующий код на веб-сайте JCA docs

byte[] desKeyData = { (byte)0x01, (byte)0x02, (byte)0x03, 
(byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08 };
DESKeySpec desKeySpec = new DESKeySpec(desKeyData);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);

Однако для ключа используется 8 байтов (вместо 7). Не ясно, соответствует ли desKeyData [0] младшему значащему байту или старшему значащему байту. Кроме того, возможно ли использовать 56-битную строку напрямую для генерации байтового массива, который можно использовать для этой цели?

Ответы [ 2 ]

7 голосов
/ 13 февраля 2011

Из Википедия :

Ключ якобы состоит из 64 бит;однако только 56 из них фактически используются алгоритмом.Восемь битов используются исключительно для проверки четности и после этого отбрасываются.Следовательно, эффективная длина ключа составляет 56 бит, и она никогда не указывается как таковая.Каждый 8-й бит выбранного ключа отбрасывается, т.е. позиции 8, 16, 24, 32, 40, 48, 56, 64 удаляются из 64-битного ключа, оставляя только 56-битный ключ.

Таким образом, младшие значащие биты (т. Е. 0-е биты) не используются для построения ключа, их можно использовать для проверки четности с помощью DESKeySpec.isParityAdjusted().

EDIT: Простой тест, показывающий, чтомладшие биты игнорируются:

SecretKeyFactory sf = SecretKeyFactory.getInstance("DES");
byte[] in = "test".getBytes("UTF-8");

Cipher c1 = Cipher.getInstance("DES");
c1.init(Cipher.ENCRYPT_MODE, sf.generateSecret(new DESKeySpec(
   new byte[] {0x10,0x20,0x30,0x40,0x50,0x60,0x70,(byte) 0x80})));
byte[] r1 = c1.doFinal(in);

Cipher c2 = Cipher.getInstance("DES");
c2.init(Cipher.ENCRYPT_MODE, sf.generateSecret(new DESKeySpec(
    new byte[] {0x11,0x21,0x31,0x41,0x51,0x61,0x71,(byte) 0x81})));
byte[] r2 = c2.doFinal(in);

assertArrayEquals(r1, r2);  
1 голос
/ 14 февраля 2011

Значимый бит - это тот, который меняет знак один или два дополнения числа. Идея старшего или младшего значащего бита не может быть применена к байтам.

Как говорит ответ axtavt, из всех 64 битов последовательности в качестве фактического ключа используются только биты в диапазонах: (1..7), (9..15), (17..23), (25..31), (33..39), (41..47), (49..55), (57..63). Например, 56 соответствующих битов в последовательности, повернутой в 1: 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, оставляя старшие биты равными нулю в качестве проверки на четность.

Чтобы фактически преобразовать последовательность из 7 байтов, 56 битов в последовательность из 8 байтов, вы можете использовать этот код .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...