2017-10-19 102 views
1

我正在嘗試編寫一個簡單的Java程序,它將使用AES-256-CBC加密純文本。有類:Java中的AES-256-CBC

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

public class AesCBC { 
    private byte[] key; 
    private byte[] iv; 

    private static final String ALGORITHM="AES"; 

    public AesCBC(byte[] key, byte[] iv) { 
     this.key = key; 
     this.iv = iv; 
    } 

    public byte[] encrypt(byte[] plainText) throws Exception{ 
     SecretKeySpec secretKey=new SecretKeySpec(key,ALGORITHM); 
     IvParameterSpec ivParameterSpec=new IvParameterSpec(iv); 
     Cipher cipher=Cipher.getInstance("AES/CBC/PKCS5Padding"); 
     cipher.init(Cipher.ENCRYPT_MODE,secretKey,ivParameterSpec); 
     return cipher.doFinal(plainText); 
    } 

    public byte[] getKey() { 
     return key; 
    } 

    public void setKey(byte[] key) { 
     this.key = key; 
    } 

    public byte[] getIv() { 
     return iv; 
    } 

    public void setIv(byte[] iv) { 
     this.iv = iv; 
    } 
} 

而且有可能的用法:

byte[] test="a".getBytes(); 

byte[] key=DatatypeConverter.parseHexBinary("b38b730d4cc721156e3760d1d58546ce697adc939188e4c6a80f0e24e032b9b7"); 
byte[] iv=DatatypeConverter.parseHexBinary("064df9633d9f5dd0b5614843f6b4b059"); 
AesCBC aes=new AesCBC(key,iv); 
try{ 
    String result=DatatypeConverter.printBase64Binary(aes.encrypt(test)); 
    System.out.println(result); 
}catch(Exception e){ 
    e.printStackTrace(); 
} 

我的輸出爲VTUOJJp38Tk+P5ikR4YLfw==,但是當我執行以下命令:

/usr/bin/openssl enc -A -aes-256-cbc -base64 -K "b38b730d4cc721156e3760d1d58546ce697adc939188e4c6a80f0e24e032b9b7" -iv "064df9633d9f5dd0b5614843f6b4b059" <<< "a" 

我得到的東西不同勢比在Java中程序(Y65q9DFdR3k1XcWhA2AO2Q==)。可悲的是,我不知道爲什麼結果不一樣,因爲我用相同的密鑰和iv使用相同的算法。這是否意味着我的Java程序無法正常工作?任何幫助,將不勝感激。

+0

您是否嘗試過使用Java和/或OpenSSL解密Java輸出?如果你再次使用OpenSSL加密,你會得到相同的輸出嗎?根據底部附近的openssl enc幫助頁面(https://wiki.openssl.org/index.php/Enc),「所有醃製選項也都過時了。」我相信如果您使用的是密鑰,OpenSSL將永遠保留您的結果。 – Jamie

回答

3

兩種方式工作正常,但是您正在加密不同的東西。

這裏的字符串語法(<<<)向字符串添加換行符。所以Java輸出是加密「a」的結果,而命令行輸出是加密「a \ n」(即字符a後跟換行符)的結果。

在命令行試試這個:

printf "a" | /usr/bin/openssl enc -aes-256-cbc -base64 -K "b38b730d4cc721156e3760d1d58546ce697adc939188e4c6a80f0e24e032b9b7" -iv "064df9633d9f5dd0b5614843f6b4b059" 

結果是VTUOJJp38Tk+P5ikR4YLfw==,符合Java結果。

0

Java結果正確,請參閱AES CALCULATOR

因此,openssl命令行加密不正確,請仔細閱讀手冊頁。

請注意,我手動添加了PKCS#7填充到輸入數據。
另外VTUOJJp38Tk+P5ikR4YLfw==(十六進制)是55350E249A77F1393E3F98A447860B7F