针对给定密钥

时间:2018-01-25 09:15:48

标签: java encryption aes

我正在尝试用Java进行AES加密。我有以下功能:

public static String encrypt(String plainText, String key) throws Exception {
    if (plainText == null || plainText.length() == 0) {
        return plainText;
    }

    // get aes key
    SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");

    // encrypt
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
    byte[] bytes = cipher.doFinal(plainText.getBytes("UTF-8"));

    //encode
    String encoded = Base64.encodeToString(bytes, Base64.NO_PADDING | Base64.NO_WRAP);

    return encoded;
}

我的目标是能够每次使用给定键以相同的方式加密某些文本。也就是说,如果我多次使用相同的两个参数调用此函数,我希望每次调用都返回相同的字符串。我会提前说,我知道密码学不应该如何完成,但我的项目需要这个功能。

不幸的是,事实并非如此。第7行中生成的密钥似乎每次都以不同方式加密我的字符串。我假设在这个库的较低层发生了某种额外的随机自动腌制,阻止了我实现目标。

有没有人在Java中知道如何每次使用给定键将给定字符串加密到相同的值?感谢。

更新/澄清:这不是为了安全。这是为了加密数据,以便对可能与处理应用程序本身有关的某些人进行模糊处理。该信息不是高度敏感,但我确实希望它被加密,然后由相同的密钥解密。我和其他人一起使用各种语言的图书馆,例如Ruby及其库允许它们每次以相同的方式使用给定键加密值。我们都希望使用相同加密算法的相同参数:密钥长度:128位 经营方式:CBC 初始化向量:无(全零)

如果没有设置初始化向量,它可能是随机分配的吗?我必须检查一下。

1 个答案:

答案 0 :(得分:1)

是的,Java - 或者更确切地说是在CBC模式实现中提供AES的安全提供程序 - 可能默认为随机IV(之后必须检索并包含密文),如果您没有明确指定它安全的,随机的密文。

如果你想使用零IV,你必须明确指定它:

cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, new IvParameterSpec(new byte[cipher.getBlockSize()]);

这比ECB模式稍微安全一些,因为初始密文块中不同消息中的任何重复都会立即被攻击者看到。

如果您想要一个没有随机IV的更安全模式 - 这是CBC模式获得CPA安全性所必需的 - 那么您可以检查合成IV(SIV)模式或GCM-SIV。对于这些模式,整个消息需要与前一个消息相同才能将信息泄露给攻击者。但速度较慢,不包含在标准VM中,密文可能比AES / CBC大(包含IV /标签与填充要求)。