从56位二进制字符串创建DES密钥

时间:2011-02-13 17:15:17

标签: java binary jca

我有一个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 个答案:

答案 0 :(得分:7)

来自Wikipedia

  

密钥表面上由64位组成;然而,算法实际上只使用了其中的56个。 8位仅用于检查奇偶校验,然后被丢弃。因此,有效密钥长度为56位,并且从未如此引用。所选密钥的每第8位被丢弃,即从64位密钥中移除位置8,16,24,32,40,48,56,64,仅留下56位密钥。

因此,最低有效位(即第0位)不用于密钥构造,它们可用于DESKeySpec.isParityAdjusted()检查奇偶校验。

编辑:简单测试显示忽略最低有效位:

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 :(得分:1)

重要一点是改变onetwo's complement号码的符号。最高或最低有效位的想法不能应用于字节。

正如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字节序列,您可以使用this code