2012-10-23 78 views
1

我得到一个错误,每次我运行此错误:由于最后一个块未正确填充

“错误:给定最后一个块未正确填充”

基本上我试图蛮力最后3密钥的字节,前13个字节是正确的。 任何想法我做错了什么?我尝试删除填充,它的工作原理,但它无法找到我确信它存在的明文,并包含单词“玛丽”。 注意:我使用sun.misc.BASE64Decoder

这里是我的代码的一部分。

 String myiv = new String(new byte[] { 
       0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x31,0x30,0x31,0x31,0x31,0x32,0x33 
     }); 

     char [] mykeyarray = new char[] {0x86,0xe5,0x30,0x90,0xff,0x62,0xa0,0x9a,0x81,0x00,0xad,0x9e,0x8f,0x00,0x00,0x00}; 
     String encoded = "dm8cfvs+c7pKM+WR+fde8b06SB+lqWLS4sZW+PfQSKtTfgPknzYzpTVOtJP3JBoU2Uo/7XWopjoPDOlPr24duuck0z+vAx91bYTwQo4INnIIBkj/lhJMWmvAKaUIO3qzBoGg8ynQOhuG6LY7Wo0uww=="; 

     IvParameterSpec ivspec = new IvParameterSpec(myiv.getBytes()); 

     byte [] decoded;  
     FileWriter fstream = new FileWriter("out.txt"); 
     BufferedWriter out = new BufferedWriter(fstream); 
     String mykey; 
     int repeat = 256; 

     outerloop: 
     for(int i=0;i<repeat;i++){ 
      for(int j=0;j<repeat;j++){ 
       for(int k=0;k<repeat;k++){ 

        mykey = new String(mykeyarray); 

        SecretKeySpec keyspec = new SecretKeySpec(mykey.getBytes(), "AES"); 

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 

        System.out.println("I: "+i+" J: "+j+" K: "+k); 

        decoded = new BASE64Decoder().decodeBuffer(encoded); 

        cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec); 

         byte [] decrypted = cipher.doFinal(decoded); 
         String dec = new String(decrypted); 

         if(dec.contains("Mary")){ 
          out.write(dec); 
          out.write("\n"); 
          System.out.println(dec); 
          break outerloop; 
         } 

          mykeyarray[15]++; 
       } 
       mykeyarray[14]++; 
       mykeyarray[15]=0x00; 
      } 
      mykeyarray[13]++; 
      mykeyarray[14]=0x00; 
      mykeyarray[15]=0x00; 
     } 
      out.close(); 
    } 

    catch(Exception e){ 
     System.out.println("Error: " + e.getMessage()); 
    } 
} 

}

回答

0

尝试学习更多关于PKCS#5填充。它是在加密之前添加到明文的特殊字节。如果文本使用错误的密钥进行解密,则不可能是正确的。如果你暴力破解密钥,除了正确的密钥外,每个密钥都会出现这个错误。

+0

为了避免这个错误,只需要设置没有填充的解密:'AES/CBC/NoPadding',所以它不会失败。您仍然会使用错误的钥匙进行垃圾回收,但您将可以看到垃圾。 – rossum

+1

你的回答不正确Pavel,'BadPaddingException'会比256次中的次数稍多一次抛出。每次解密在十六进制结束时都是'01',这将是一个正确的PKCS5Padding('0202'等也是一个,但是这当然不太可能发生)。这并不意味着密钥是正确的,或者说得到的纯文本是正确的。 –

+0

好的,我没有计算出随机块中正确填充的概率。我只是解释了例外的原因。 –

1

你的代码犯了很多很多错误,我不知道你在做什么。所以,我会解释为什么您可能会收到一个BadPaddingException的CBC加密:

  • 你的密钥不正确已经改变
  • 一个或多个模块具有
  • 一个或两个密文的最后两个块从密文
  • 的端部被除去的IV是不正确的,所述密文是由一个单独的块

好运狩猎向下异常的原因的。

0

由于用随机密钥解密会给你一个随机消息,所以你通常没有得到正确的填充。赶上例外,继续前进。

当暴力破解PKCS5填充消息时,您会得到大约93%的填充错误。 PKCS5填充填充消息的字节包含填充的长度。因此,有效的填充是0x01,0x2,0x02,0x03x03x03,...,0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF。正确填充发生在随机消息中的几率是1/16 +(1/16)^ 2 ...(1/16)^ 16 < .067。这意味着你得到不正确的填充约1-%6.7 = 93%的时间。

相关问题