8

我有一个 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 位字符串来生成可用于此目的的字节数组?

4

2 回答 2

7

来自维基百科

密钥表面上由 64 位组成;但是,算法实际使用了其中的 56 个。八位仅用于检查奇偶性,然后被丢弃。因此,有效密钥长度为 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);  
于 2011-02-13T17:55:52.473 回答
1

有效位是改变二补数符号的位。最高或最低有效位的想法不能应用于字节。

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

于 2011-02-13T23:18:11.253 回答