MasterKey = 256 - 512 bits of CS random entropy
然后,在加密时:
Salt = 256 bits of random entropy
Derivation = PBKDF2(SHA-512, MasterKey, Salt, 10000, 640bit)
CipherKey = Derivation[0:256bit]
AuthKey = Derivation[256bit:512bit]
IV = Derivation[512bit:640bit]
然后,盐就是全部在密文包中共享:
Salt || CipherText || AuthText
... 这里的几点:
MasterKey应该是高熵的(至少是加密安全随机作为最长所需密钥)。
盐也应尽可能地实用(CS也应如此),因为盐冲突将自动变为密码,身份验证密钥和IV冲突。
单个派生密钥的最大长度应为小于PBKDF2中使用的PRF的块大小(如果找到派生密钥,则减少主密钥的暴露)。
例如,如果您使用MD5(128位bs)生成256位密钥,则如果发现256位密钥(强力或其他弱点),则整个128位输出将会找到PBKDF2回合。因此,整个PBKDF2输出不需要强行使用,而只需进行一轮即可(仍然很困难,但要容易得多)。但是,如果BS较大(sha512与256位密钥),那么找到派生密钥只会给您一轮输出的1/2,这会使搜索更加困难(因为有很多输入会产生相同的1 / 2输出)...
馈入PBKDF2的迭代计数应足够高,以提供派生工作的证明,但显然取决于应用程序。
根据我的理解,它显示出良好的前向安全性(虽然不是完美的,但很好),因为如果您能够找到特定消息的CipherKey或AuthKey,则它们将不适用于将来或过去的消息。您将需要使用该信息来强行推导,这至少是微不足道的。因此,只要不破坏主密钥,各个派生密钥就应该安全并且实际上彼此独立。
我在这里吗?还是我想念的东西?
#1 楼
是的,这是一种很好的方法。这种技术称为“密钥分离”。由于主密钥是加密安全密钥,因此不需要使用大量的迭代次数。另外,您可以使用任何PRF代替PBKDF2。 (如果将PBKDF2应用于密码短语而不是加密安全密钥,通常会使用迭代计数;但是从安全角度来看,这本质上是有问题的,所以您做的更好。)
例如,您可以使用HKDF或AES-CMAC作为您的PRF。 HKDF产生任意长度的输出,因此您可以将其用作PBKDF2的插件替代:
Derivation = HKDF(MasterKey)
,然后按照您的描述继续进行。使用AES-CMAC的标准方法是使用MasterKey
作为CMAC密钥,并对要导出的每个值使用不同的消息输入:例如,CipherKey = CMAC(MasterKey, 0)
,AuthKey = CMAC(MasterKey, 1)
,IV = random()
(或IV = CMAC(MasterKey, 2)
)。(有关密钥分离的更多信息,用于密钥派生的标记Wiki包含一组非常简短的关键字,可能会帮助您找到更多的关键字。)
信用:感谢@CodesInChaos建议将HKDF作为一个合理的方法。
#2 楼
由于一个好的块加密算法,例如在计数器模式下运行的AES,即加密或多或少任意选择的(对手未知)输入值,通常被认为是足够安全的,恕我直言,它可以提供一种相当简单方便的方法来从中派生大量密钥给定的主密钥。一种方法甚至可以通过使用包含相应年,月等的输入来获取从要使用的主密钥生成的主密钥的层次结构,例如,用于特定的特定年份,月份等。评论
$ \ begingroup $
加密算法的秘密部分应该是密钥,而不是明文。在计数器模式下,输入通常是已知的。
$ \ endgroup $
–PaŭloEbermann
2012年12月9日在16:07
$ \ begingroup $
@PaŭloEbermann:对。对于计数器模式,密钥通常是秘密的。明文部分是一个任意数值,通常连续递增1(或任何数量),但该输入也可以形成任意值序列(例如,包含时间和消息序列号等),尽管不必因安全原因受到非常严格的保护)。
$ \ endgroup $
–沉莫功
2012-12-10 11:21
$ \ begingroup $
我记得很多年前在另一个论坛中曾提到过以反模式通过分组密码从主密钥派生密钥的方法,尽管当时甚至认为这个想法很可能是古老且广为人知的。但是最近,在其他地方的讨论中,我得到的印象是它可能尚未广为人知,可能是由于文献中没有提及。在s13.zetaboards.com/Crypto/index中的代码JADE中提到了具有主密钥层次结构以动态派生会话密钥的想法。
$ \ endgroup $
–沉莫功
2012-12-10 14:17
$ \ begingroup $
@PaŭloEbermann实际上,CTR模式是为不经常重复的任何序列定义的,计数器只是最简单的方法(并且具有最大的周期)。因为$ \ gcd {(3,2 ^ n)} = 1 $,所以递增3与递增1一样有效,但是这样做的用处非常大。
$ \ endgroup $
–托马斯
2012年12月14日的1:10
$ \ begingroup $
@Thomas:我相信我已经在文献中看到过“通用计数器”一词,用于确定性的非重复序列。
$ \ endgroup $
–伊尔马里·卡洛宁(Ilmari Karonen)
2013年1月11日在2:09
评论
如果主密钥是随机的,为什么需要“工作证明”?@dchest:你不知道。工作量证明是从随机密钥到密码密钥(如果您能够破解,则很难从密码密钥向后退)...
如果您的密钥具有256位熵,并且密钥推导函数是单向的,则在密钥推导中添加或删除迭代不会使暴力破解变得特别困难或容易-1次迭代已经足够困难。在处理密码时,需要迭代,因为密码没有足够的熵。
我会使用HKDF进行密钥推导