我试图了解这个简单的AES加密代码的工作情况以及它可能面临的漏洞。
public static void main(String ... args) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
1) String key = "/AbCd17%%/gvg8(";
2) byte[] keyBytes = key.getBytes();
3) SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
4) Cipher cipher = Cipher.getInstance("AES");
5) cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
6) byte[] ciphertext = cipher.doFinal("Message".getBytes());
7) System.out.println(ciphertext);
}
到目前为止,我认为问题在于以下几点:
- >第2行和第2行6使用getBytes()而不是首先使用getBytes(" UTF8")编码键/明文,但这究竟是如何构成威胁的呢?
- >在第4行,我们使用ECB模式(默认模式)是不安全的,所以我们应该使用其他模式,如OCB,CTR等。
- >列出的例外是否会导致任何漏洞?我还缺少什么?
我对这些东西不熟悉,并希望得到任何帮助。
答案 0 :(得分:1)
首先 - 你可能试图在Java中查看at my blog加密,这是非常基本的,但至少你会得到一些提示如何正确加密
1)String key =“/ AbCd17 %% / gvg8(”;
2)byte [] keyBytes = key.getBytes();
简单key.getBytes()
将一直有效,直到使用可在默认系统编码下打印的字符。
还有另一个(更大的)问题 - 您正在使用静态字符串键,它将键空间限制为可打印字符。您应该使用byte[]
来获取密钥并由KeyGenerator或至少SecureRandom生成。
密钥也可以基于密码,因为您可以查看链接的博客如何从密码生成密钥。 (或搜索PBKDF2)
4)密码密码= Cipher.getInstance(“AES”); - >在第4行,我们使用ECB模式(默认模式)是不安全的,所以我们应该使用其他模式,如OCB,CTR等。
恕我直言,最佳做法是明确指定操作模式和填充,例如AES/CBC/PKCS5Padding
。如果您没有指定任何标准,我不确定标准是什么(某些密码默认使用ECB模式,我不确定AES)。
除ECB模式外,还使用IV(初始化矢量)。 IV未经指定时随机生成(您可以从密码对象中读取它)。恕我直言最佳做法是创建一个随机的IV,明确地使用加密和解密。它使代码更具可读性。
IV将沿着密文提供。
6)byte [] ciphertext = cipher.doFinal(“Message”.getBytes()); 7)System.out.println(密文);
你不能只打印一个字节数组,你需要以某种方式对数据进行编码(base64,hex,..)
我还缺少什么?
您可能仍然缺少的是mac(消息身份验证代码),它经常被忽略,但我发现它非常重要,here是一些选项。