2015-11-06 24 views
2

。如果我加密/解密一個字符串,它是小於16字節的加密工作正常,但如果我喂密碼任何大於16個字節我得到的錯誤「由於最後塊未正確填充」。我內置一些小的代碼爲例:AES解密工作不適合我在使用Java中的AES加密/解密一個很奇怪的問題,超過16個字節

package com.company; 

import javax.crypto.Cipher; 
import javax.crypto.spec.IvParameterSpec; 
import javax.crypto.spec.SecretKeySpec; 

public class Main { 

    public static void main(String[] args) { 
     try { 
      Cipher aesEncrypt = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
      Cipher aesDecrypt = Cipher.getInstance("AES/CBC/PKCS5Padding"); 

      SecretKeySpec key = new SecretKeySpec("ABCDEQWERTASDFGA".getBytes(), "AES"); 

      IvParameterSpec ivSpec = new IvParameterSpec(new byte[16]); 

      aesDecrypt.init(Cipher.DECRYPT_MODE, key, ivSpec); 
      aesEncrypt.init(Cipher.ENCRYPT_MODE, key, ivSpec); 

      byte[] message = "Hello".getBytes(); 

      aesEncrypt.update(message); 

      byte[] encrypted = aesEncrypt.doFinal(); 

      aesDecrypt.update(encrypted); 

      byte[] decrypted = aesDecrypt.doFinal(); 

      System.out.println(new String(decrypted, "UTF-8")); 
     } 
     catch (Exception e){ 
      e.printStackTrace(); 
     } 
    } 
} 

當字節[]消息「你好」的加密/解密工作正常,但是當我將其更改爲「HelloMyBabyHelloMyDarling」它拋出異常。有人知道我在這裏做錯了嗎?

+0

請參閱[這裏](http://security.stackexchange.com/questions/29993/aes-cbc-padding-when-the-message-length-is-a-multiple-of-the-block-size)有關_padding_上的一些信息 – sokin

回答

3

Cipher#update(byte[])返回一個你不使用某種原因byte[]。你乾脆扔掉一切,除了最後一個塊(Cipher#doFinal()應用於填充後返回的最後加密塊)。如果你的消息只包含一個單獨的塊,那麼密文和解密後的明文將會完成。

由於您使用的短消息,那麼你就需要使用Cipher#update可言。只需使用Cipher#doFinal(byte[])

byte[] message = "Hello".getBytes(); 
byte[] encrypted = aesEncrypt.doFinal(message); 
byte[] decrypted = aesDecrypt.doFinal(encrypted); 

如果你想加密更長的數據(這可能不適合到內存中),那麼你應該寫Cipher#update結果到OutputStream或使用CipherOutputStream沒有updatedoFinal電話。