首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从主键生成2个独立的密钥

从主键生成2个独立的密钥
EN

Cryptography用户
提问于 2018-07-13 13:49:05
回答 2查看 1.8K关注 0票数 4

这个场景是这样的:为了不同的目的,我需要两个密钥(加密+加密,加密+ mac,等等)。因为重用相同的密钥不是很好的实践,所以我希望这两个键是独立的。但是记住两个不同的键是很麻烦的(请不要质疑这个问题),所以我认为应该有一些方法从一个普通的主键生成这些键。

我能找到的最接近这项工作的密码工具是一个KDF。然而,KDF通常作为额外的输入: salt。我应该随机生成并记住一个salt,还是简单地使用一个哈希函数(如SHA512 )并将其输出分成2个键?

我认为在这种情况下,不需要担心从派生密钥中恢复主键的可能性,因为派生密钥的重要性不亚于主键。派生密钥的危害与主键的危害一样严重。相反,重点是两个派生密钥之间的独立性,因为至少有一些加密和mac方案,在一起使用时,如果密钥不是独立的,就会完全崩溃。

EN

回答 2

Cryptography用户

发布于 2018-07-13 22:45:01

  • 盐的目的是限制对手在多个目标之间分担的成本。盐不一定是随机的。它只需要是唯一的每个用户。如果两个用户共享一个盐(可能是一个空盐),那么找到至少一个密钥的工作可以在一个奥奇斯林彩虹桌上与并联机共享,这样在一次批处理多目标攻击中找到至少一个密钥的预期成本大约是单目标攻击预期成本的一半,而找到至少一个密钥的预期时间最多是单个目标攻击预期时间的八分之一。通常,如果存在n可能的键和t目标,并且并行处理关于p \geq t^2的计算,那么至少查找一个键的预期成本是n/t,第一个目标的预期查找时间是n/pt,最多是关于n/t^3的。如果您使用256位键,那么需要使用的用户数量不可能很高,因此在这种情况下可以安全地使用空盐。salt只对≤128位键很重要.(这就是为什么AES-128应该被认为具有一个<128位的安全级别,以及为什么要使用AES-256。)如果您有一个键唯一的用户id的概念,您可以将它与应用程序的名称连接为salt,而不需要存储。如果您没有唯一的用户id的概念,那么使用随机盐可以降低敌人在两个攻击目标之间共享工作的可能性。盐的时间越长,碰撞的可能性就越低,使对手能够共享工作。使用256位的盐,除非你的实现被破坏,否则不会发生冲突.
  • KDF的第二个目的是将高熵但可能是非均匀秘密映射为统一秘密。如果您的主密钥来自Diffie-Hellman密钥协议,并且是剩余类模的唯一代表的位串编码--一个大的安全素数,或者是椭圆曲线上某个点的字节字符串编码,那么主密钥不是均匀分布在位字符串之间,而是具有很高的熵。KDF平滑了位字符串上的分布,因此它实际上是一致的。
  • 密码散列(scrypt、argon2等)的用途就是使用所有可用资源来提高对散列的单个评估的成本,而蛮力攻击必须重复这样做。愿意花1秒在散列上吗?迫使对手计算200万(比方说)HMAC-say 256计算,而不是每次猜测一次。愿意花1GB内存在散列上吗?强迫对手在每个并行哈希电路中提交1GB内存的区域--如果不是内存的话,这个区域本来可以用于更多的并行哈希电路--比如PBKDF2 2--或者花费双倍的时间进行散列,如果它们只能容纳512 MB RAM,等等。如果你不能增加这个秘密的可能性,例如,如果你的秘密是由一个人选择的,你至少可以提高在一次野蛮攻击中测试每一种可能性的成本。

--这些注意事项独立适用:

  • 有一个人工选择的密码?可能有≪128位熵。使用密码散列(如argon2id和salt ):(a)提高每次猜测的成本;(b)将非均匀位字符串映射到统一位字符串;(b)防止对手在多个目标之间共享工作。确保用户是否更改了密码,salt也发生了变化,因此如果它是确定的选择,它不能只是一个应用程序名称和用户id-它还必须包括一个修改号。
  • 是否从{\sim}2^{128}的可能性中选择了机器生成的令人难忘的diceware密码?使用类似于KDF的HKDF和salt来(a)将128位熵的非均匀位串转换为统一的位串,以及(b)防止对手在多个目标之间共享工作。如果只在交互应用程序中使用密码哈希来提高每次猜测的成本,这并不会有什么影响,但这是不必要的。
  • 根据x密钥协议对Curve25519上的X25519坐标进行共享秘密编码,从而使x^3 + 486662 x^2 + x是二次剩余模2^{255} - 19?使用类似于HKDF的KDF将其转换为统一的随机位字符串。在这种情况下盐渍并不伤人,但没有必要。
票数 8
EN

Cryptography用户

发布于 2018-07-14 01:03:41

记住一把钥匙很麻烦,更别提两把了。加密密钥应该由大约128位组成,这样才是安全的。记住密码或密码是足够困难的。密码不是秘密/对称密钥,因为它不包含随机位。

基本上有两种类型的KDF。一种是使用密码作为主要输入材料的KDF,称为PBKDF:一个基于密码的密钥派生函数。第二种方法是将键作为主输入,称为KBKDF:基于键的密钥派生函数。

PBKDF和KBKDF都可能需要盐,但盐对PBKDF来说更重要。这是因为,否则两个相同密码的输出可能很容易识别。此外,没有盐,彩虹表可以用来尝试和找到密码。密钥的强度也会减弱,特别是多次使用时,但密钥的初始强度要比常规密码高得多,因此,对于192位或更高的密钥大小较大的密钥,削弱强度将不那么明显或不适用。

KBKDF也可能需要盐,但它主要用于简化KBKDF的证明。如果输入键确实包含足够的熵,那么没有它的KDF应该是安全的。香港发展基金可以接受一个盐作为输入,香港发展基金标准包含一部分关于盐如何帮助确保香港发展基金的输出-提取在第3.1章。

要从密码中派生出两个密钥,PBKDF和KDF的使用都是最不易碎的(我的意思是:如果PBKDF或KBKDF有问题,则最不可能中断)。

你会得到:

K_m = \text{PBKDF}(\mathit{work}, \mathit{salt}, \mathit{passphrase})
K_1 = \text{KBKDF}(K_m, \mathit{label}_1)
K_2 = \text{KBKDF}(K_m, \mathit{label}_2)
\ldots

这样,您只需要一个salt,就可以对密码执行密钥增强,并且密钥K_1K_2是独立的。密码可以是任何实际大小。当然,它仍然必须是相对强大的,否则它可能是野蛮的,强迫的,或发现使用(增强的)字典攻击。

如果您想使用两个现代实现,您可以使用一个Argon2变体作为PBKDF和HKDF或HKDF-展开为KBKDF。

请注意,\mathit{work}参数可能包括要执行的CPU工作的元素、并行性以及函数的内存硬度。\mathit{label}通常是名为\mathit{OtherInfo}或仅\mathit{info}的结构的一部分,该结构还可能包含标识或分隔输出键的其他数据。每个标准都可以使用稍微不同的参数名称和符号。

原则上,如果您真的可以记住一个键,那么您可以只使用KBKDF,但这非常麻烦:

代码语言:javascript
复制
17a2ae1904debd903e090d5c7fb0a0e3

是显示为32十六进制的128位随机密钥。

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

https://crypto.stackexchange.com/questions/60775

复制
相关文章

相似问题

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