8

I have a 56 bit binary string that i want to use as the secret key for DES encryption.

I found the following code at the JCA docs website

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);

However this uses 8 bytes for the key (instead of 7). It is not clear if the desKeyData[0] corresponds to the least significant byte or the most significant one. Also, is it possible to use the 56 bit string directly to generate the byte array that can be used for this purpose ?

AnkurVj
  • 7,958
  • 10
  • 43
  • 55
  • 1
    An 8-byte input normally means it's using the 7 least significant bits of each byte. – Jerry Coffin Feb 13 '11 at 17:20
  • and which byte is the most significant ? the 0th or the 7th ? – AnkurVj Feb 13 '11 at 17:30
  • 1
    Most importantly, why in the world are we still using DES in 2011? (the first to reply "backwards compatibility" will earn the "You-didn't-get-my-point-did-you?" badge) – CAFxX Feb 13 '11 at 18:17
  • the number 0x01 has the least significant bit set to 1, and the number 0x80 has the most significant bit set to 1. – vz0 Feb 13 '11 at 18:32
  • @vz0 - i meant in the byte array .. is the byte at index 0 the least significant byte ? – AnkurVj Feb 13 '11 at 19:30

2 Answers2

7

From Wikipedia:

The key ostensibly consists of 64 bits; however, only 56 of these are actually used by the algorithm. Eight bits are used solely for checking parity, and are thereafter discarded. Hence the effective key length is 56 bits, and it is never quoted as such. Every 8th bit of the selected key is discarded, i.e. positions 8, 16, 24, 32, 40, 48, 56, 64 are removed from the 64 bit key leaving behind only the 56 bit key.

So, the least significant bits (i.e. 0th bits) are not used for key construction, they can be used for checking parity by DESKeySpec.isParityAdjusted().

EDIT: Simple test showing that the least significant bits are ignored:

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
  • 239,438
  • 41
  • 511
  • 482
  • bit positions 8,16 etc .. doesnt this mean most significant bits of each byte instead of least significant bits ? – AnkurVj Feb 13 '11 at 18:07
  • Starting at one, the parity bits are the most significant of every byte. – vz0 Feb 13 '11 at 23:25
1

A significant bit is the one that changes the sign of a one or two's complement number. The idea of a most-or-least significant bit can not be applied to bytes.

As axtavt answer says, from all the 64 bits of the sequence only the bits in the ranges: (1..7), (9..15), (17..23), (25..31), (33..39), (41..47), (49..55), (57..63) are used as the actual Key. For example, the 56 relevant bits on the sequence turned to 1 are: 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, leaving the most significant bits to zero as parity check.

To actually convert a 7 bytes, 56 bits sequence to an 8 byte sequence you can use this code.

vz0
  • 32,345
  • 7
  • 44
  • 77
  • 1
    From the code you are referring to, setting a parity bit: `result[7-resultIx/8] |= 1;`. Least significant bits are used for parity check in this case. – axtavt Feb 14 '11 at 08:05
  • @axtavt if i split my 56 bit binary string into a big endian byte array , the msb of any byte may be '1' however the byte data type does not allow this ( its range is -2^7-1 to 2^7-1). Is type casting the correct solution to this ? I want to know that if i type cast these into bytes will i be still be using the same key that i wanted to use ? – AnkurVj Feb 14 '11 at 09:32