DES 蛮力(学术)

Ana*_*aty 6 java encryption cryptography des brute-force

我正在上计算机安全课程,我们的一项任务是对具有弱密钥的 DES 进行暴力破解。

我的代码:

    public static void main(String[] args) throws Exception {
        String temp;
        String current;
        String plaintext;
        
        //Generate key for DES
        String initkey = "00000006";
        byte[] Rawkey = initkey.getBytes();
        DESKeySpec dks =  new DESKeySpec(Rawkey);
        SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
        SecretKey desKey = skf.generateSecret(dks);
        
        //Text Enc & Dec
        Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
        
        //Declare wether to enc or dec
        cipher.init(Cipher.ENCRYPT_MODE,desKey);
        byte []message = "Decrypted Successfully".getBytes();
        byte []messageEnc = cipher.doFinal(message);
        plaintext = new String(message);
        System.out.println("Cipher Text: " + new String(messageEnc) );

        for(int i=0;i<10;i++){
            try{
                temp = padLeftZeros(Integer.toString(i),8);
                System.out.println(temp);
                byte []RawkeyTest = temp.getBytes();
                DESKeySpec dksTest =  new DESKeySpec(RawkeyTest);
                SecretKeyFactory skf2 = SecretKeyFactory.getInstance("DES");
                SecretKey desKeyTest = skf2.generateSecret(dksTest);
                cipher.init(Cipher.DECRYPT_MODE,desKeyTest);
                byte []dec = cipher.doFinal(messageEnc);
                current = new String(dec);
                if(current.equals(plaintext)){
                    System.out.println("Decrypted Text: " + current);
                    System.out.println("");
                    //break;
                }
                
            }catch (BadPaddingException ex){
                System.out.println("Wrong Key.");
                System.out.println("");
            }
            
        }
   
    }

    public static String padLeftZeros(String inputString, int length) {
        if (inputString.length() >= length) {
            return inputString;
        }
        StringBuilder sb = new StringBuilder();
        while (sb.length() < length - inputString.length()) {
            sb.append('0');
        }
        sb.append(inputString);
    
        return sb.toString();
    }
}
Run Code Online (Sandbox Code Playgroud)

输出

Cipher Text: ?
B??4#??`=???H??:?
00000000
Wrong Key.

00000001
Wrong Key.

00000002
Wrong Key.

00000003
Wrong Key.

00000004
Wrong Key.

00000005
Wrong Key.

00000006
Decrypted Text: Decrypted Successfully

00000007
Decrypted Text: Decrypted Successfully

00000008
Wrong Key.

00000009
Wrong Key.

00000010
Wrong Key.

00000011
Wrong Key.

00000012
Wrong Key.

00000013
Wrong Key.

00000014
Wrong Key.

00000015
Wrong Key.

00000016
Decrypted Text: Decrypted Successfully

00000017
Decrypted Text: Decrypted Successfully

00000018
Wrong Key.

00000019
Wrong Key.
Run Code Online (Sandbox Code Playgroud)

密钥#6 是唯一应该成功解密的密钥。所以我不明白为什么 key: 7, 16, 17 也有效。

任何帮助或建议将不胜感激。提前致谢。

kel*_*aka 5

没有问题,实际上,有一个。

DES 通常使用 64 位密钥,其中每个字节的最后一位 (lsb) 是奇偶校验位,总共有 56 位加密密钥。奇偶校验位对密钥调度没有贡献。这就是我们说 DES 具有 56 位密钥大小的原因。一旦检查奇偶校验,它们就会被丢弃。密钥的每个字节必须具有奇校验。该库忽略了奇偶校验问题并且不提供异常。

  • 0x0...6 = 0x..01107=0x..0111。如果您删除正确的位,它们是相同的。

  • 0x0..16 = 0x...0001 011017=0x...0001 0111。现在删除每个字节中的最后一位,那么密钥将与0x00000006

并请注意,上述密钥都不是奇偶校验有效的。如果要检查奇偶校验或使密钥有效,可以使用Alejandro Revilla github 中的以下 Java 代码

public static void adjustDESParity (byte[] bytes) {
    for (int i = 0; i < bytes.length; i++) {
        int b = bytes[i];
        bytes[i] = (byte)((b & 0xfe) | ((((b >> 1) ^ (b >> 2) ^ (b >> 3) ^ (b >> 4) ^ (b >> 5) ^ (b >> 6) ^ (b >> 7)) ^ 0x01) & 0x01));
    }
}

public static boolean isDESParityAdjusted (byte[] bytes) {
    byte[] correct = (byte[])bytes.clone();
    adjustDESParity(correct);
    return  Arrays.equals(bytes, correct);
}
Run Code Online (Sandbox Code Playgroud)

如果您正在寻找 DES 的弱密钥,那么这些是

0101 0101 0101 0101
1F1F 1F1F 0E0E 0E0E
E0E0 E0E0 F1F1 F1F1
FEFE FEFE FEFE FEFE
Run Code Online (Sandbox Code Playgroud)