能否使用空字符串作为AES算法的SecretKeySpec?
能不能用空字符串作为AES的SecretKeySpec?
嘿,这个问题问得够直接,咱们拆解来说:
结论先行:绝对不可以,不管从语法合规性还是安全性来说,这都是错误且危险的做法
1. AES密钥有严格的长度要求
AES算法明文规定密钥长度必须是128位(16字节)、192位(24字节)或256位(32字节)。你用空字符串""调用getBytes("UTF8")得到的是0字节的数组,完全不符合AES的密钥规范。
虽然有些JDK实现可能不会在创建SecretKeySpec时立刻抛出异常,但在后续调用Cipher.init()或者doFinal()的时候,大概率会抛出IllegalArgumentException或其他加密相关异常——不同环境表现可能有差异,但本质上这是违反算法标准的操作。
2. 安全层面等于完全没加密
退一万步说,就算你的代码侥幸能运行,空密钥意味着加密完全失效。任何拿到密文的人都可以轻松还原出明文,这和直接明文传输没有任何区别,完全失去了加密的意义,属于严重的安全漏洞。
3. 你的示例代码还有个小问题
顺便提一句,你写的加密代码里,doFinal的调用方式存在逻辑问题:
byte[] b = new byte[instance.getBlockSize()]; instance.doFinal(b, instance.update(bytes, 0, bytes.length, b, 0));
update方法会返回写入b的字节数,doFinal应该从这个位置继续写入,否则可能会覆盖数据或者导致解密失败。正确的写法应该是:
byte[] b = new byte[instance.getOutputSize(bytes.length)]; // 用getOutputSize计算准确的输出长度 int updateLen = instance.update(bytes, 0, bytes.length, b, 0); int finalLen = instance.doFinal(b, updateLen); // 最终加密后的有效字节是b数组中从0到updateLen+finalLen的部分
正确的做法
如果你需要生成AES密钥,推荐用标准的密钥生成器:
KeyGenerator keyGen = KeyGenerator.getInstance("AES"); keyGen.init(128); // 也可以选192、256位,注意256位可能需要JCE无限制权限策略 SecretKey secretKey = keyGen.generateKey();
如果是从用户密码生成密钥,应该用PBKDF2这类密钥派生算法,结合随机盐值来生成符合长度要求的密钥。
内容的提问来源于stack exchange,提问作者Neo
相关产品推荐
相关产品推荐

