Создать ключ DES из 56-битной двоичной строки

У меня есть 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 ответов


С Википедия:

ключ якобы состоит из 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);  

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

Как говорит ответ 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 байт, вы можете использовать код.