所以我的问题直截了当 有人可以使用空字符串作为带有AES的SecretKeySpec
String a = "";
Key secretKeySpec = new SecretKeySpec(a.getBytes("UTF8"), "AES");
然后用它来加密字符串
String str = "String that needs encoding";
byte[] bytes = str.getBytes("UTF8");
Cipher instance = Cipher.getInstance("AES/ECB/PKCS7Padding");
instance.init(1, secretKeySpec);
byte[] b = new byte[instance.getBlockSize()];
instance.doFinal(b, instance.update(bytes, 0, bytes.length, b, 0));
String str2 = new String(Base64.encode(b));
这只是整个代码的片段
答案 0 :(得分:1)
这不会起作用,因为AES的密钥大小固定为16字节(128位),24字节(192位)或32字节(256位)。
空的SecretKeySpec意味着你正在使用长度为0的密钥。我认为这将最终出现在以下异常中:
java.lang.IllegalArgumentException: Empty key
BTW:你的代码很奇怪,因为它会对数据进行部分加密两次:
instance.doFinal(b, instance.update(bytes, 0, bytes.length, b, 0));
首先instance.update
将内容从bytes
加密到b
。然后instance.doFinal
再次加密b
的内容。
答案 1 :(得分:0)
任何字符串都不应该直接用作键,所以对我来说这个问题毫无意义。如果要从密码短语生成密钥,则应使用密码哈希,例如PBKDF2,bcrypt,scrypt或Argon2。
对称密钥由多个位组成,通常是字节或八位字节。对于对手来说,这些字节应该是完全随机的。如果它们不存在那么你将无法实现对称密码所承诺的安全性。
您可以将密钥存储为十六进制或基本64.但是不建议这样做,因为对于许多托管语言(如Java),字符串通常永久保存在内存中。如果一个密钥(最初)由字节组成,那么这些字节应该在不再需要时立即清除。
请注意,对于需要密码的95%的情况,ECB不是安全操作模式。而是使用安全的操作模式,例如GCM,并为密文添加唯一或安全的随机(12字节)IV。
这取决于加密函数实现接受哪种密钥,即使它们没有意义(毕竟你期望至少128位的随机性)。例如,HMAC身份验证 - 不是密码 - 接受任何大小的密钥。但是,Java实现似乎需要SecretKeySpec
至少一个字节。
总而言之,我想空的字符串就在那里让你填写。