AES加密在ECB模式下实现,但不符合安全性。如何实现CBC模式

时间:2016-06-03 12:46:52

标签: java security encryption aes cbc-mode

我在java中实现了AES加密,但团队不接受该算法,因为它是在ECB模式下实现的,这不符合安全性。我对加密和安全要求很新。

有人可以帮我改变算法到CBC模式。我附上了以ECB模式实现的代码。

public String encrypt(String plainPwd)
{
    byte[] outputBytes = new byte[] {};
    String returnString = "";
    try
    {
        byte[] raw = "XXXXX@XXXXXX.XXX".getBytes("UTF-8");

        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);

        outputBytes = cipher.doFinal(plainPwd.getBytes("UTF-8"));
        if (null != outputBytes)
        {
            returnString = Base64Encrypter.getInstance().encode(outputBytes);
        }
        return returnString.trim();

    }
    catch (Exception e)
    {
        System.out.println(e);
    }

    return new String(outputBytes).trim();
}

public String decrypt(String encryptedPwd)
{
    byte[] outputBytes = new byte[] {};
    try
    {
        byte[] raw = "XXXXX@XXXXXX.XXX".getBytes("UTF-8");

        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec);

        byte[] inputBytes = Base64Encrypter.getInstance().decode(encryptedPwd);
        if (null != inputBytes)
        {
            outputBytes = cipher.doFinal(inputBytes);
        }
    }
    catch (Exception e)
    {
        System.out.println(e);
    }

    return new String(outputBytes).trim();
}

早期回复将受到高度赞赏。 提前致谢

3 个答案:

答案 0 :(得分:0)

如果您的数据很短并且随机ECB可能是可接受的(至少不比CBC差)。但是,最好不要试图做到这一点。

请记住,CBC也不提供完整性保护。使用额外的HMAC或专用模式来包装机密(AESKeywrap)或使用经过身份验证的模式(AES / GCM)会更好。 (这不仅是一个避免修改的问题,它还会关闭一系列针对协议隐私保护的攻击)。

如果数据不是随机/可预测的,则需要使用也使用IV的模式。在CBC的情况下,如果没有指定,Java将选择随机IV。

但是对于解密(特别是如果你有一个填充验证)你需要指定完全相同的IV,所以不要忘记检索和传输它。因此(不安全,因为未经过身份验证)加密变为:

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
byte[] iv = cipher.getIV(); // randomly filled.
...

// on decrypt specify this IV again
cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(iv));

这也有一个优点,它实际上指定了要使用的填充,因此您不依赖于Java的默认选择(总是指定完整模式字符串)。

答案 1 :(得分:0)

AES有大约6种不同的加密模式。为您正在使用它的应用程序使用正确的模式非常重要。正如@eckes所说,ECB适用于随机加密/解密访问很有用的少量数据。 ECB的缺点是相同的输入将具有相同的输出,因此如果实际值的数量有限,攻击者可以看到模式并可以对其进行逆向工程。

查看how to choose AES encryption mode以获取有关选择正确操作模式的更多指导。

答案 2 :(得分:0)

将请求字符串从AES更改为AES/CBC/PKCS5PADDING并添加iv。虽然填充不是CBC特定的,但明确定义所有参数是好的,除了少数例外,需要填充。

对于iv,生成加密安全的随机数块大小(AES为16字节)。为了使iv可用于解密,通常的做法是将其添加到加密数据中,它不需要保密。