2017-05-26 46 views
0

我想用AES加密实现一个自定义密钥,并且我已经找到了下面的实现和关于这个的详细信息。如何使用存储在密钥库中的自定义密钥执行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 + usern ame + password)“使用SHA-1/2并将byte []数组传递给SecretKeySpec?
  3. 为什么我无法将明文密钥作为字节[]发送?
  4. 我试图确保“密钥”是动态的,以便它基于salt +用户名+ my_custom_secret_key,以便相同的加密字符串将具有不同的输出。

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?

回答

2

解答您的疑惑:

  1. 如何/我应该在哪里存储我的秘密密钥即 “mysecretkey_123456”?

这取决于。我所看到的似乎是一个密码而不是一个关键。因此将其存储在您的头部或密码管理器将被建议。

  • 为什么有需要 “散列” 的 “(SALT2 +用户名+密码)” 组合使用SHA-1/2和传递byte []数组来SecretKeySpec?
  • 这是因为AES密钥由正好是16,24或32个字节,其应该是随机的给攻击者。密码既没有一致的长度,也没有要求的随机性。

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

    如果你的“明文钥匙”之称my_custom_secret_key已经具备了强度的128位或更多,那么你可以使用基于密钥密钥导出函数,如香港民主促进会代替。

  • 为什么不能发送明文秘密密钥作为字节[]?
  • 谁说你不能?代码示例似乎错误地输入了密钥和密码,所以我认为这是混淆的来源。您通常会使用高熵密钥的字节。

    对于使用char[]密码建议;这是因为在用它来验证密码或派生密钥之后,您不能销毁String的内容。另一方面,char[]可以在使用后直接用零填充来清除。当然,这对存储在byte[]中的密钥也同样适用。

  • 我试图确保“密钥”是动态的,使得它是基于一个盐+用户名+ my_custom_secret_key,使得相同的加密字符串将具有不同的输出。
  • 只要盐大和足够的随机,将工作,说16个字节SecureRandom再生每盐所需的加密时间。

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

    +0

    我想2个Java程序之间共享我的所谓的AES“自定义密码”这样我们就可以使用相同的密钥来加密和解密数据。出于安全原因,我如何保护/存储我的“自定义密码”? – youcanlearnanything

    +0

    我想使用“密码”而不是密钥的原因是因为我希望密文在每次使用时都改变。即基于每次服务器启动,或每个用户的会话或每个用户的事务。 – youcanlearnanything

    +0

    在系统密钥存储,拇指驱动器上,在受保护的帐户,在启动过程中输入它,在一个加密的配置文件。完整的密钥管理在这里讨论有点多。当您需要完全自主的应用程序时,您可能只能*密码*密码。最后你需要将它存储在某个地方,再次加密会导致鸡蛋问题。 –