如何使用存储在密钥库中的自定义密钥执行AES加密?

时间:2017-05-26 15:48:27

标签: java encryption cryptography

我想用AES加密实现自定义密钥,我找到了以下实现和详细信息。

byte[] key = (SALT2 + username + my_custom_secret_key).getBytes("UTF-8");
MessageDigest sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
key = Arrays.copyOf(key, 16); // use only first 128 bit

SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");

但我有以下疑问:

byte[] my_key = (SALT2 + username + my_custom_secret_key).getBytes("UTF-8");
SecretKeySpec secretKeySpec = new SecretKeySpec(my_key, "AES");

如果我使用典型的示例代码,例如:

KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(128);
SecretKey secretKey = keyGen.generateKey();
  1. 我应该如何/在哪里存储我的密钥,即" mysecretkey_123456"
  2. 为什么需要"哈希" "(SALT2 +用户名+密码)"的组合使用SHA-1/2并将byte []数组传递给SecretKeySpec?
  3. 为什么我不能将明文密钥发送为byte []?
  4. 我正在努力确保"键"是动态的,因此它基于salt + username + my_custom_secret_key,因此相同的加密字符串将具有不同的输出。
  5. Java AES and using my own Key

    https://www.securecoding.cert.org/confluence/display/java/MSC61-J.+Do+not+use+insecure+or+weak+cryptographic+algorithms

    How to generate SALT value in Java?

1 个答案:

答案 0 :(得分:2)

回答你的怀疑:

  
      
  1. 我应该如何/在哪里存储我的密钥,即" mysecretkey_123456"?
  2.   

这取决于。我所看到的似乎是密码而不是密钥。因此,建议将其存放在头脑或密码管理器中。

  
      
  1. 为什么需要"哈希" "(SALT2 +用户名+密码)"的组合使用SHA-1/2并将byte []数组传递给SecretKeySpec?
  2.   

这是因为AES密钥恰好包含16,24或32个字节,对于攻击者来说应该是随机的。密码既不具有一致的长度,也不具有所需的随机性。

代码段的作用是创建密码散列函数或基于密码的密钥派生函数(PBKDF)。当然只是使用SHA-1不会削减它,你应该使用PBKDF2或bcrypt,scrypt或Argon2之一。然后使用高工作因子(或迭代计数)配置其中一个功能,以提供密钥加强。 PBKDF2 - 尽管不是最好的 - 是Java运行时环境的一部分,使其部署起来相对容易。

如果你的"明文密钥"名为my_custom_secret_key已经具有128位或更多的强度,那么您可以使用基于密钥的密钥派生函数,例如HKDF。

  
      
  1. 为什么我不能将明文密钥发送为byte []?
  2.   

谁说你不能?代码示例似乎弄错了密钥和密码,所以我认为混淆来自哪里。您通常会使用字节作为高熵密钥。

建议使用char[]的密码;这是因为在您使用它来验证密码或导出密钥后,您无法销毁String的内容。另一方面,char[]可以通过在使用后直接填充零来清除。这同样适用于存储在byte[]中的密钥。

  
      
  1. 我正在努力确保"键"是动态的,因此它基于salt + username + my_custom_secret_key,因此相同的加密字符串将具有不同的输出。
  2.   

只要盐很大且足够随机,只要每次加密需要一个盐就会重新生成16个字节SecureRandom,这将会起作用。

这样生成的密钥将始终足够随机,并且在使用安全模式时(即,使用Java ECB中的任何模式构建,最好是像GCM模式加密一样),加密将是安全的。 / p>