我有一项服务,每个用户都有一个API密钥。我需要存储密钥,以便它们可用于验证API请求。
如果我将密钥以明文形式存储在我的数据库中,我担心有人访问数据库的情况,抓取所有明文api密钥,然后使用它们冒充其他人(可能会更大)但是,如果有人有权访问数据库,则会出现问题。
这类似于存储用户密码,您只需存储哈希并使用它进行验证 - 但是大多数API都允许您查看API密钥,这意味着它们需要以某种可恢复的方式存储。
这是最好的做法吗?
答案 0 :(得分:11)
有人获取数据库并获取密钥的威胁意味着他们可以使用api密钥访问数据库中已有的数据,因此无法在那里获胜。
有人可以访问数据库,获取密码的威胁意味着他们可以在具有相同用户名的其他网站上重复使用这些密码,因为人们倾向于重复使用他们的密码。
明确或容易可逆的密码的另一个原因是公司中的某个人可以获得密码,并开始做坏用户的行为。如果您的API密钥是明确的,那么您可能面临的风险。
通常,HMAC是一种解决方案,用于从单个密钥和一些公共值加密计算安全值。
看看HMAC。使用HMAC,您可以使用应用程序将密钥加载到内存中(配置文件,读取amazon KMS,输入应用程序启动,或者您希望在那里获取该密钥)。
在数据库中,存储令牌。例如Token = UUID()
。令牌对于用户应该是唯一的,令牌可以在需要重新生成时进行版本控制,并且令牌可以是随机的(如UUID)。令牌并不是秘密。
使用密钥(SK
)和用户令牌(UT
)计算API密钥,如下所示:
API_SECRET = HMAC(SK, UT)
然后将API_KEY
和API_SECRET
分发给用户,当用户尝试连接时,您计算API_SECRET
:
计算数据库中UT的API_SECRET:
API_SECRET_DB = HMAC(SK,UT)
将计算出的API_SECRET_DB
与请求中提供的值进行比较:
if(API_SECRET_DB == API_SECRET_FROM_REQUEST){ //登录用户 }
最重要的是,您只保护密钥,而不是每个凭证。
答案 1 :(得分:-1)
我对一些用PHP编写的库进行了更新,这使得它使用模拟保护算法(IPA)。导致不将令牌本身保存在数据库中。
有关详细信息,请查看此https://github.com/vzool/api-hmac-guard
希望它有所帮助,谢谢