在我的系统中,每个用户都可以拥有多个api密钥。我想哈希api密钥并在数据库中存储它们的哈希值。我正在使用comeonin。
1)存储api键的哈希值而不是它们原始的原始值是否合理?
2)当api请求进入时,其中只有一个普通的api密钥值,并且没有用户电子邮件 - 这是我的系统设计的。
我应该如何检查api密钥是否有效?我是否必须这样做 - 重新计算哈希?
given_api_plain_key = get_key_from_request()
# re-hash it again
# but how about the original salt???
given_api_hash_key = Comeonin.Bcrypt.hashpwsalt(given_api_plain_key)
case Repo.get_by(ApiKey, key_hash: given_api_hash_key) do
nil -> IO.puts("not found")
a -> IO.puts("gooood")
end
或者有更好的方法吗?
答案 0 :(得分:3)
(1)存储api密钥的哈希值而不是它们简单的原始值是否明智?
您的目标似乎是防止在有人访问您的数据库时可能发生的重大妥协(例如,通过SQL注入,命令注入或系统上的反向shell)。在这种情况下,是的,这是明智的,特别是如果每个用户具有不同的API密钥。但是,this link值得阅读可能会影响您决定的其他注意事项。
(2)我应该如何检查api密钥是否有效?
很明显,您需要对输入进行哈希处理,看看是否与数据库中的内容匹配。
(3)实施。
您不希望应用与密码相同的保护。密码本质上往往具有低熵,因此我们需要像bcrypt这样的工具来处理它们。 Bcrypt设计缓慢(防止暴力攻击),并使用盐来帮助选择密码错误的安全性。
API密钥不应具有低熵,因此您不需要慢速函数来处理它们。实际上,缓慢的功能会带来DoS风险,因此您绝对不希望每次请求都进行bcrypt。Salting也会使您的用例变得复杂(当您知道谁在提供输入时,salt工作,但在您的情况下,您不会知道它是从哪里来的。)
简短回答:只需使用SHA256,无需盐。