java AES加密在ECB模式下实现,但不符合安全性要求。如何实施CBC模式
我已经用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();
}
如能早日答复,将不胜感激。 提前谢谢
# 1 楼答案
如果您的数据较短且随机,ECB可能是可以接受的(至少不比CBC差)。但这很可能是一个好主意,甚至不要试图让这一点是正确的
请记住,CBC也不提供完整性保护。使用额外的HMAC或专用模式包装机密(AESKYWRAP)或使用身份验证模式(AES/GCM)更好。(这不仅仅是一个避免修改的问题,它还关闭了一类针对协议隐私保护的攻击)
如果数据不是随机/可预测的,则需要使用一种模式,该模式也使用IV。对于CBC,如果未指定,Java将选择随机IV
然而,对于解密(特别是如果您有一个填充来进行验证),您需要指定完全相同的IV,所以不要忘记检索和传输它。因此(由于未经验证而不安全)加密变为:
这还有一个优点,即它实际上指定了要使用的填充,因此您不依赖于Java的默认选择(始终指定完整模式字符串)
# 2 楼答案
将请求字符串从
AES
更改为AES/CBC/PKCS5PADDING
,并添加一个iv。虽然填充不是特定于CBC的,但最好显式定义所有参数,除少数例外情况外,需要填充对于iv,生成块大小的加密安全随机数(AES为16字节)。为了使iv可用于解密,通常的做法是将其预加密到加密数据中,它不需要是机密的
# 3 楼答案
AES有大约6种不同的加密模式。对于正在使用它的应用程序,使用正确的模式非常重要。正如@eckes所说,ECB对于随机加密/解密访问有用的少量数据来说是合适的。ECB的缺点是,相同的输入将具有相同的输出,因此攻击者可以看到模式,如果实际值的数量有限,则可以对其进行反向工程
查看how to choose AES encryption mode了解有关选择正确操作模式的更多指导