密钥派生函数(Argon2、Scrypt 和 PBKDF2)

密钥派生函数或KDF从秘密值派生一个或多个秘密密钥。 因此,如果您曾经需要在数据库中存储密码或通过密码创建私钥,则可能使用了KDF。

例如,一些流行的KDF的示例:

  • Argon2
  • Scrypt
  • PBKDF2

密钥派生功能是大多数Web应用程序所必需的。 使用纯文本或弱哈希密码存储的站点数量令人恐惧。 如果某个站点通过电子邮件向您发送了密码副本,请运行!

KDF只是哈希函数吗?

不,但是有重叠。 为了理解KDF,让我们首先快速了解一下散列函数。

例如一些哈希函数:

  • SHA-256
  • MD5

哈希函数接受输入并创建输出。 在大多数密码哈希方案中,它看起来像这样:

sha256( "password123" ) -> ef92b778bafe771e89245b89ecbc08a44a4e166c06659911881f383d4473e94f

该函数必须具有以下属性:

  • 它确定性地加扰数据(相同的输入,相同的输出)
  • 无论输入如何,哈希函数的输出始终具有相同的大小
  • 它无法从输出中检索输入(单向功能)

那么区别是什么呢?

有不同类型的KDF。 其中一些是基于流或分组密码的,但是在本文中,我们将重点介绍最常见的类型, 即基于散列的密钥派生函数

事实证明,所有基于哈希的KDF都是安全的哈希函数,但并非所有哈希函数都是基于哈希的KDF。

密钥派生函数(Argon2、Scrypt 和 PBKDF2)_第1张图片

除了散列函数的属性,KDF还可以用于以下目的 :

  • 按键伸展
  • 重点美白
  • 密钥分离
  • 重点加强

让我们分别考虑每种情况,并牢记以下一般KDF的定义:

derivedKey = keyDerivationFunction(originalKey, salt, difficulty)

Salt是用于防止预计算攻击或rainbow表的随机数据。

通过大量的计算、内存或并行性要求,可以使用难度使KDF变慢。 这样可以防止暴力攻击,因为每次猜测会使攻击者花费更长的时间。

密钥弹性

对于普通开发人员而言,密钥扩展是最常见的用例。 这个想法是采用具有低熵(安全性或随机性)的密钥,并将其扩展为更安全的更长密钥。 密码无疑是一个很好的例子。 例如,许多网站使用Bcrypt来扩展密钥:

passwordForDB = bcrypt(password, salt, difficulty)

密钥分离

KDF允许从主密钥创建子密钥。 可以在比特币之类的应用中使用,其中子密钥可以控制钱包的各个部分。 但是,只有主节点具有完全控制权。 这是通过使用不同的盐来完成的。 例如:

childOne = kdf(masterKey, saltOne, difficulty)
childTwo = kdf(masterKey, saltTwo, difficulty)
childThree = kdf(masterKey, saltThree, difficulty)

重点加强

加强使用随机盐扩展密钥,但随后删除该盐,因此无法再次使用。 这使得生成的密钥更强大,而又不增加系统的重大漏洞。

我应该使用KDFs吗?

是的。 最通常在将密码存储在数据库中时使用,但是如果其他任何用例都属于您的代码领域,也是如此。 如果您有任何意见或疑问,请向我发推文。 要了解更多信息,请查看HKDF文件 。

原文链接: https://hackernoon.com/an-introduction-to-key-derivation-functions-argon2-scrypt-and-pbkdf2-g23s32is

你可能感兴趣的:(密钥派生函数(Argon2、Scrypt 和 PBKDF2))