首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >密码学:用密码加密而不存储密码。

密码学:用密码加密而不存储密码。
EN

Security用户
提问于 2017-06-27 20:42:34
回答 5查看 998关注 0票数 2

我正在开发一个桌面应用程序,在这个应用程序中,我们处理敏感数据,我们希望用密码加密本地文件,当用户打开应用程序时,我们会问他。在大多数类似的项目中,我们看到人们存储密码的散列,以便在尝试解密所有密码之前验证密码是否有效。这暴露了一个安全问题,因为哈希可以很容易地从外部提取并强制执行。

我们要做的是在文件的开头放置一个静态文本来解密,当用户输入密码时,应用程序尝试解密该印章,如果可以的话,这将意味着密码是有效的,然后他可以继续解密文件的其余部分。

安全吗?由于我在任何地方都没有看到这种情况,所以我不确定我是否忽略了一些可能使这个系统变得脆弱的东西。

编辑:

我想重温这个问题,因为从那以后我学了很多密码学。

显然,正确的答案是“不要自己动手,用一个库来做那些知道自己在做什么的人”。

基本上,问题是在试图用密码解密一个大文件之前,如何验证密码是否正确。我今天推荐的基本方案是生成一个随机密钥,使用它加密文件,然后使用一个由强KDF(如Argon2、Scrypt、BCrypt或PBKDF2)和AEAD (如ChaCha20Poly1305、AES-GCM )生成的密钥包装它,或者如果您信任更新的算法,您可以使用Deoxys-II或Ascon之类的方法。这样,密码就可以更改,而无需重新加密文件,而且您的代码可以轻松地检查密码是否有效。这有点类似于KeePass和其他密码管理器的做法,只不过他们通常使用“常规”密码+ HMAC而不是AEAD。

博士:密码是复杂的,使用一个库。

EN

回答 5

Security用户

回答已采纳

发布于 2017-06-28 06:46:04

TL;DR:使用适当的密钥派生函数,而不是使用本地的方案。

哈希可以很容易地提取出来,并在外部强制执行。

我认为您低估了预图像攻击在现代密码哈希函数上的难度。

安全吗?由于我在任何地方都没有看到这种情况,所以我不确定我是否忽略了一些可能使这个系统变得脆弱的东西。

如果做得对,你提出的建议可能不会真的很脆弱,但它也可能不会给你买多少钱。正如以前的答案所讨论的那样,做错了事情,它可能会变得极度不安全。

基本上,当您考虑对密码进行散列时,不要只考虑您的平均密码散列函数(如MD5或SHA512 )的一轮。相反,您的第一选择应该是使用正确的基于密码的密钥推导函数。有许多这样的选择,但目前比较流行的选择似乎是PBKDF2bcrypt氪石越来越受欢迎。

与普通的哈希基元不同,密钥派生函数被专门设计为速度慢,并且尽量给攻击者提供尽可能少的优势,即使攻击者能够使用自定义硬件攻击用户输入的密码,即使该密码的熵相对较低。

您仍然可以存储一些指示密码是否正确的内容。例如,卢克斯通过存储主密钥的盐水加密散列来实现这一点;如果用户提供的密码没有正确地解密任何密钥插槽,那么密钥槽中的主密钥数据的解密将产生一个不正确的结果,从而产生一个不同的主密钥哈希,该散列被检测到并作为“不正确的密码短语”进行操作。请注意,在这种情况下,密码本身的散列没有存储。比较磁盘上的LUKS格式,图1 PHDR布局。

票数 1
EN

Security用户

发布于 2017-06-27 21:14:07

尝试使用类似PBKDF2的方法将密码转换为密钥,然后用它对文件进行加密。PBKDF2提供了盐渍和迭代配置,使蛮力变得更加困难。

票数 2
EN

Security用户

发布于 2017-06-28 01:58:46

在大多数类似的项目中,我们看到人们存储密码的散列,以便在尝试解密所有密码之前验证密码是否有效。这暴露了一个安全问题,因为哈希可以很容易地从外部提取并强制执行。

这是一个不正确的解决方案,但并不是因为你给出的原因。事实上,任何密码是唯一秘密的加密方案都允许攻击者进行和测试密码猜测。此问题只能通过要求密码之外的其他内容才能避免。

我们要做的是在文件的开头放置一个静态文本来解密,当用户输入密码时,应用程序尝试解密该印章,如果可以的话,这将意味着密码是有效的,然后他可以继续解密文件的其余部分。

这是有缺陷的,因为您试图使用加密来检查密码的有效性,但是加密并不提供这样的保证。

这里的正确解决方案相当复杂,而且很容易出错。我能说什么密码很难。要加密文件,以下是一个不完整的步骤大纲:

  1. 每次您重新加密一些数据时,使用加密安全的随机数生成器生成一个新的随机盐。
  2. 使用基于密码的密钥派生函数(如PBKDF2、scrypt或Argon2id )从随机盐和用户输入的密码中派生加密密钥。
  3. 使用派生密钥使用认证加密算法(即.a)加密数据。(A),以盐作为相关数据。AEAD将输出一个经过身份验证的密文--其中包含一个身份验证标记,将在解密过程中进行检查。
  4. 把盐和密文写到文件里。

要解密文件:

  1. 从加密文件中读取盐分。
  2. 向用户询问密码,并使用salt (提供的密码)重建密钥。
  3. 试着解密密文。由于您使用的是AEAD,如果密码是不正确的,解密将失败与一个真实性错误。

提高安全性的一种方法是将盐类存储在文件之外的其他地方,攻击者不太可能找到这些盐类。例如,1 password密码管理器将salt称为“秘密钥匙”,它将salt与加密的密码库文件分开存储在设备中。在线同步传输密文,但用户必须在设备之间手动复制密钥。

票数 2
EN
页面原文内容由Security提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://security.stackexchange.com/questions/162914

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档