在服务器上存储API密钥

在服务器上存储API密钥,api,security,Api,Security,我有一个服务,每个用户都有一个API密钥。我需要存储密钥,以便它们可以用于验证API请求 如果我将密钥以明文形式存储在数据库中,我担心会出现这样的情况:有人访问数据库,获取所有明文api密钥,然后使用它们模拟其他密钥(不过,如果有人访问数据库,可能会出现更大的问题) 这类似于存储用户密码,您只需存储散列并使用散列进行验证,但是大多数API允许您查看API密钥,这意味着它们需要以某种可恢复的方式存储 是否有最佳实践?有人获得数据库并获得密钥的威胁意味着他们可以使用api密钥访问数据库中的数据,而他

我有一个服务,每个用户都有一个API密钥。我需要存储密钥,以便它们可以用于验证API请求

如果我将密钥以明文形式存储在数据库中,我担心会出现这样的情况:有人访问数据库,获取所有明文api密钥,然后使用它们模拟其他密钥(不过,如果有人访问数据库,可能会出现更大的问题)

这类似于存储用户密码,您只需存储散列并使用散列进行验证,但是大多数API允许您查看API密钥,这意味着它们需要以某种可恢复的方式存储


是否有最佳实践?

有人获得数据库并获得密钥的威胁意味着他们可以使用api密钥访问数据库中的数据,而他们已经拥有了这些数据,因此没有赢家

有人可以访问数据库、获取密码的威胁意味着他们可以在具有相同用户名的其他网站上重复使用这些密码,因为人们倾向于重复使用他们的密码

另一个原因是,你的公司可能有人掌握了密码,并开始以用户的身份做坏事。如果您的API密钥处于透明状态,那么这可能是一种风险

通常,HMAC是一种通过加密方式从单个密钥和某些公共值计算安全值的解决方案

看看HMAC。使用HMAC,您可以使用应用程序将密钥加载到内存中(配置文件、读取amazon KMS、在应用程序启动时键入密钥,或者以您希望的方式获取密钥)

在数据库中,存储一个令牌<例如,code>Token=UUID()。令牌对于用户来说应该是唯一的,可以对令牌进行版本控制,以防您需要重新生成,并且令牌可以是随机的(如UUID)。代币不是秘密

使用密钥(
SK
)和用户令牌(
UT
)计算API密钥,如下所示:

API_SECRET = HMAC(SK, UT)
然后将
API_密钥
API_秘密
分发给用户,当用户尝试连接时,计算
API_秘密

  • 从数据库获取用户记录(您可能已经要求用户提供其用户名)
  • 从数据库中的UT计算API_机密:

    API_SECRET_DB=HMAC(SK,UT)

  • 将计算的
    API\u SECRET\u DB
    与请求中提供的值进行比较:

    如果(API_SECRET_DB==API_SECRET_FROM_REQUEST){ //登录用户 }


  • 总之,您只保护密钥,而不是每个凭证。

    我对用PHP编写的某个库进行了更新,该库使用了模拟保护算法(IPA)。这会导致不将令牌本身保存在数据库中

    有关更多信息,请查看此


    希望有帮助,谢谢

    为什么不使用服务器密钥加密每个API密钥呢?当API密钥通过请求传入时,对其进行加密,并将其与存储的加密值进行比较。如果需要显示API密钥,请解密存储的值。HAMC是一种单向加密,通常用于这些类型的场景。考虑它是一种加密,除了它是一种方式,所以你不能解密数据。OP询问查看API密钥。对于不需要恢复原始密码的单向散列,我将使用密码散列,例如bcrypt或scrypt,这样您就可以进行密钥拉伸和加密。您需要bcrypt对8个字符的密码进行拉伸和加密。您不需要bcrypt来“拉伸”256位随机字符串(SK)。我们正在讨论API键以及如何防止它们在数据库中被查看。不是短密码,而是人们可以记住的密码。通过增加位大小/熵的大小,可以最好地延长时间。