在服务器上存储API密钥

use*_*425 18 security api

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

如果我将密钥以明文形式存储在我的数据库中,我担心某人有权访问数据库,抓取所有明文api密钥,然后使用它们冒充他人(如果有人访问,可能会有更大的问题)尽管如此).

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

这是最好的做法吗?

Jon*_*han 15

有人获取数据库并获取密钥的威胁意味着他们可以使用api密钥访问他们已经拥有的数据库中的数据,因此没有胜利.

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

密码明确或容易可逆的另一个原因是公司中的某个人可以获得密码,并开始做坏用户的行为.如果您的API密钥是明确的,那么您可能面临的风险.

通常,HMAC是用于从单个秘密密钥和一些公共值加密计算安全值的解决方案.

看看HMAC.使用HMAC,您可以使用应用程序(配置文件,读取亚马逊KMS,输入应用程序启动,或者您想在那里获取该密钥)将密钥加载到内存中.

在数据库中,存储令牌.Token = UUID()例如.令牌对于用户应该是唯一的,令牌可以在需要重新生成时进行版本控制,并且令牌可以是随机的(如UUID).令牌并不是秘密.

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

API_SECRET = HMAC(SK, UT)
Run Code Online (Sandbox Code Playgroud)

然后分发API_KEYAPI_SECRET给用户,当用户尝试连接时,您计算API_SECRET:

  1. 从数据库获取用户记录(您可能已经要求用户提供其用户名)
  2. 从数据库中的UT计算API_SECRET:

    API_SECRET_DB = HMAC(SK,UT)

  3. 将计算结果API_SECRET_DB与请求中提供的计算结果进行比较:

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

最重要的是,您只保护密钥,而不是每个凭证.

  • OP询问有关查看API密钥的信息。对于不需要恢复原始哈希的单向哈希,我将使用例如bcrypt或scrypt之类的密码哈希,以便获得密钥扩展和加密。 (2认同)
  • 谢谢@jonathan,还有一个问题,用户用他们的 UT 做什么?看来用户只需要存储和使用“API_SECRET”,对于用户来说,它的外观和行为与 API 密钥完全相同。 (2认同)