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

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

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

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-битную строку напрямую для создания массива байтов, который можно использовать для этой цели?


person AnkurVj    schedule 13.02.2011    source источник
comment
8-байтовый ввод обычно означает, что он использует 7 младших битов каждого байта.   -  person Jerry Coffin    schedule 13.02.2011
comment
а какой байт самый старший? 0-й или 7-й?   -  person AnkurVj    schedule 13.02.2011
comment
Самое главное, почему мы все еще используем DES в 2011 году? (первый, кто ответит на обратную совместимость, получит значок «Вы не поняли мою точку зрения?»)   -  person CAFxX    schedule 13.02.2011
comment
в числе 0x01 младший бит установлен в 1, а в числе 0x80 старший значащий бит установлен в 1.   -  person vz0    schedule 13.02.2011
comment
@ vz0 - я имел в виду массив байтов ... является ли байт с индексом 0 наименее значащим байтом?   -  person AnkurVj    schedule 13.02.2011


Ответы (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);  
person axtavt    schedule 13.02.2011
comment
битовые позиции 8,16 и т. д. не означает ли это, что старшие значащие биты каждого байта вместо младших значащих битов? - person AnkurVj; 13.02.2011
comment
Начиная с единицы, биты четности являются старшими в каждом байте. - person vz0; 14.02.2011

Значимым битом является тот, который изменяет знак единицы или < число href="http://en.wikipedia.org/wiki/Two%27s_complement" rel="nofollow">дополнение до двух. Идея старшего или младшего бита не может быть применена к байтам.

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

person vz0    schedule 13.02.2011
comment
Из кода, на который вы ссылаетесь, установка бита четности: result[7-resultIx/8] |= 1;. В этом случае для проверки четности используются младшие значащие биты. - person axtavt; 14.02.2011
comment
@axtavt, если я разделю свою 56-битную двоичную строку на массив байтов с обратным порядком байтов, старший бит любого байта может быть «1», однако тип данных byte не позволяет этого (его диапазон от -2 ^ 7-1 до 2 ^ 7 -1). Является ли приведение типов правильным решением для этого? Я хочу знать, что если я наберу их в байты, буду ли я по-прежнему использовать тот же ключ, который я хотел использовать? - person AnkurVj; 14.02.2011