为什么我需要两个密钥才能进行AES加密?

use*_*232 2 java encryption aes

我正在尝试为某些文本实现AES加密,我正在寻找一种解决方案,最终归结为一个加密和解密密码.我在这个网站上找到了一个可行的解决方案:简单的Java AES加密/解密示例

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

import org.apache.commons.codec.binary.Base64;

public class Encryptor {
    public static String encrypt(String key1, String key2, String value) {
        try {
            IvParameterSpec iv = new IvParameterSpec(key2.getBytes("UTF-8"));

            SecretKeySpec skeySpec = new SecretKeySpec(key1.getBytes("UTF-8"),
                    "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
            byte[] encrypted = cipher.doFinal(value.getBytes());
            System.out.println("encrypted string:"
                    + Base64.encodeBase64String(encrypted));
            return Base64.encodeBase64String(encrypted);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    public static String decrypt(String key1, String key2, String encrypted) {
        try {
            IvParameterSpec iv = new IvParameterSpec(key2.getBytes("UTF-8"));

            SecretKeySpec skeySpec = new SecretKeySpec(key1.getBytes("UTF-8"),
                    "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
            byte[] original = cipher.doFinal(Base64.decodeBase64(encrypted));

            return new String(original);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {

        String key1 = "Bar12345Bar12345"; // 128 bit key
        String key2 = "ThisIsASecretKet";
        System.out.println(decrypt(key1, key2,
                encrypt(key1, key2, "Hello World")));
    }
}
Run Code Online (Sandbox Code Playgroud)

这个算法使用key1和key2,不明白为什么他们需要这两个.每个密钥的用途是什么,将key1保留为所有时间并将密钥2替换为个人密码是否安全?

谢谢

dna*_*ult 7

'key1'是你的密钥.在此代码中,通过在密码上调用String.getBytes()来获取字节数组.请参阅此答案,了解为什么这是不可取的,以及一些建议的替代方案.

'key2'被错误命名; 它实际上是一个初始化向量(或简称为"IV").这是一个随机的字节序列,可以防止同一个明文始终被转换为相同的密文.

应使用SecureRandom.getBytes()为每个加密消息生成随机IV .对于AES,IV应为16字节(128位).IV 不是秘密 ; 它应该与密文一起发送,以便收件人可以使用它(连同密钥)来解密消息.

加密后,我建议将IV字节前置到密文字节,然后对结果字节数组进行Base64编码.

至于代码的结构,没有必要将IV传递给加密方法; 加密方法可以在内部生成IV.同样,如果密文以IV为前缀,那么您不需要将IV传递给decrypt方法; 相反,decrypt方法可以假设消息的前16个字节是IV.

一般来说,仅加密并不能确保消息没有被篡改.如果要检测攻击者何时篡改加密邮件,可以类似HMAC 的邮件验证代码应用于 iv + cyphertext.