我试图编写一个简单的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 :(得分:3)
两种方式都正常工作,但是你正在加密不同的东西。
此处的字符串语法(<<<
)为字符串添加换行符。因此Java输出是加密“a”的结果,命令行输出是加密“a \ n”的结果(即字符a
后跟换行符。)
从命令行尝试:
printf "a" | /usr/bin/openssl enc -aes-256-cbc -base64 -K "b38b730d4cc721156e3760d1d58546ce697adc939188e4c6a80f0e24e032b9b7" -iv "064df9633d9f5dd0b5614843f6b4b059"
结果为VTUOJJp38Tk+P5ikR4YLfw==
,与您的Java结果相匹配。
答案 1 :(得分:0)
Java结果是正确的,请参阅AES CALCULATOR。
因此openssl命令行加密不正确,请仔细阅读手册页。
请注意,我手动将PKCS#7填充添加到输入数据中
十六进制中的VTUOJJp38Tk+P5ikR4YLfw==
也是55350E249A77F1393E3F98A447860B7F
答案 2 :(得分:0)
很好地记录和解释。美妙的例子。如果数据是 ASCII 而不是十六进制,您可能需要扩展您的代码。
// when data is ASCII
byte[] key="abcdefghi123456".getBytes();
byte[] iv="1234567890123456".getBytes();