简体   繁体   English

Java 中的 AES-256-CBC

[英]AES-256-CBC in Java

I'm trying to write a simple Java program that will encrypt plain text with AES-256-CBC .我正在尝试编写一个简单的 Java 程序,该程序将使用AES-256-CBC加密纯文本。 There is class:有课:

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;
    }
}

And there is possible usage:并且有可能的用法:

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();
}

My output is VTUOJJp38Tk+P5ikR4YLfw== , but when I execute this command:我的输出是VTUOJJp38Tk+P5ikR4YLfw== ,但是当我执行这个命令时:

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

I get something diffrent than in Java program( Y65q9DFdR3k1XcWhA2AO2Q== ).我得到了与 Java 程序不同的东西( Y65q9DFdR3k1XcWhA2AO2Q== )。 Sadly I have no idea why results aren't the same since I use the same algorithm with the same key and iv.可悲的是,我不知道为什么结果不一样,因为我使用相同的密钥和 iv 使用相同的算法。 Does it mean my Java program doesn't work properly?这是否意味着我的 Java 程序不能正常工作? Any help would be appreciated.任何帮助将不胜感激。

Both ways are working correctly, however you are encrypting different things.两种方式都可以正常工作,但是您正在加密不同的东西。

The here string syntax ( <<< ) adds a newline to the string. here 字符串语法 ( <<< ) 向字符串添加换行符。 So the Java output is the result of encrypting "a", and the command line output is the result of encrypting "a\\n" (ie the character a followed by a newline).所以Java输出是加密“a”的结果,命令行输出是加密“a\\n”的结果(即字符a后跟换行符)。

Try this from the command line:从命令行试试这个:

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

the result is VTUOJJp38Tk+P5ikR4YLfw== , matching your Java result.结果是VTUOJJp38Tk+P5ikR4YLfw== ,与您的 Java 结果匹配。

The Java result is correct, see AES CALCULATOR . Java 结果是正确的,请参阅AES CALCULATOR

Thus the openssl command line encryption is incorrect, read the man page carefully.因此 openssl 命令行加密不正确,请仔细阅读手册页。

Note that I added the PKCS#7 padding manually to the input data.请注意,我在输入数据中手动添加了 PKCS#7 填充。
Also VTUOJJp38Tk+P5ikR4YLfw== in hex is 55350E249A77F1393E3F98A447860B7F十六进制中的VTUOJJp38Tk+P5ikR4YLfw==也是55350E249A77F1393E3F98A447860B7F

Very nicely documented and explained.很好地记录和解释。 Wonderful Example.美妙的例子。 You may want to extend your code if the data is ASCII instead of hex.如果数据是 ASCII 而不是十六进制,您可能想要扩展您的代码。

// when data is ASCII
byte[] key="abcdefghi123456".getBytes();
byte[] iv="1234567890123456".getBytes();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM