我正在尝试在java中编写一个简单的密码管理器。我想使用AES 256位加密使用存储的密码加密文件。此外,我希望用户能够使用密码解密文件。当在线阅读其他帖子时,他们几乎都强调单纯使用密码作为密钥是不安全的,他们提到使用随机盐来增加安全性。但我不明白在生成密钥时如何使用随机盐。如果我从用户的密码和随机盐创建密钥,那么当他们尝试解密他们的文件时,我怎么知道盐是什么?这让我完全糊涂了。
目前,我在每一步使用常量盐通过几个不同的哈希运行密码。这是否足够安全,或者我错过了什么?任何有关如何从密码安全生成密钥的帮助将不胜感激!提前谢谢。
答案 0 :(得分:8)
请记住盐不是秘密。您只需将其附加到加密数据即可。盐的目的是防止某人使用通用密码加密的常见数据片段的预先计算字典来“破解”加密文件。
通过确保盐随机并将其与密码相结合,您可以消除字典攻击的可能性,因为(有效)黑客没有机会拥有数据库用你的“盐+密码”加密。 (作为入门者,请参阅我的一个教程,在salts in password-based encryption上查看此页面。)
您还(有效地)消除了冲突的问题:在两个文件中使用相同密码的情况下,如果两个文件中出现的相同数据块看起来可能会给攻击者提供内容的线索同样在加密版本中。
但是,您仍然需要采取其他预防措施,因为典型的密码通常不包含太多 entropy 。例如,8个完全随机的小写字母将产生大约40位的熵;遵循典型英语模式的8个小写字母将产生大约20比特的熵。换句话说,在2 ^ 256个可能的密钥中,实际上典型的用户将在2 ^ 20-2 ^ 40范围内的一些小部分中进行选择。在精明的用户的情况下,情况变得更好,但你将不太可能接近256位的熵。 (考虑到在“密码短语”中,每个字符将有大约2.5-3位的熵,所以一个30个字符的密码短语给你大约75位的熵 - 说实话,有多少人使用任何东西比如30个字符的密码?使用'完整'范围的可打印ASCII的8个完全随机的字符会给你一点64位以下。)
缓解这种情况的一种方法是转换密码(附加盐)使用计算复杂的单向函数以便它将需要黑客再试一下他们想要猜测的每一把钥匙。再次,see this page for more details。
为了让您大致了解基于密码的文件加密的缺陷,您可能还想看看我几年前写的Arcmexer library,其中包括一个名为isProbablyCorrectPassword的方法( )。结合用于生成候选密码的字典/算法,您可以使用它来衡量上述方法的有效性(因为ZIP文件加密使用这些技术的组合)。
答案 1 :(得分:1)
使用此库:http://www.jcraft.com/jsch/
有一个很好的AES示例:
http://www.jcraft.com/jsch/examples/AES.java.html
很多大牌都使用这个包,Maven,Eclipse等。