我遇到了许多提供用户API密钥和秘钥的API。但我的问题是:两者之间有什么区别?
在我看来,一个密钥就足够了。假设我有一个密钥,只有我和服务器知道它。我使用此密钥创建HMAC哈希并进行API调用。在服务器上,我们再次创建HMAC哈希并将其与发送的哈希进行比较。如果相同,则调用已通过身份验证。
那么为什么要使用两个密钥呢?
编辑:或者该API密钥用于查找API秘钥吗?
我遇到了许多提供用户API密钥和秘钥的API。但我的问题是:两者之间有什么区别?
在我看来,一个密钥就足够了。假设我有一个密钥,只有我和服务器知道它。我使用此密钥创建HMAC哈希并进行API调用。在服务器上,我们再次创建HMAC哈希并将其与发送的哈希进行比较。如果相同,则调用已通过身份验证。
那么为什么要使用两个密钥呢?
编辑:或者该API密钥用于查找API秘钥吗?
简单回答,如果我理解正确的话...
如果您使用API密钥进行加密,服务将如何知道是谁在联系他们?他们如何解密该消息?
您使用API密钥来说明您是谁,这是您以明文形式发送的内容。 您不会向任何人发送SECRET密钥。您只需将其用于加密,然后发送加密消息。您不会发送用于加密的密钥,否则就失去了加密的目的。
在这里我没有看到提到的一件事,虽然这是Marcus Adams答案的扩展,但如果有时序攻击的可能性,您不应该使用单个信息来标识和验证用户,因为时序攻击可以利用响应时间的差异猜测字符串比较的进程。
如果您正在使用一个系统来使用“键”查找用户或凭证,那么这个信息可以通过发送成千上万的请求并检查数据库查找(或未找到)记录所需的时间来逐步猜测。如果“键”以明文而不是“键”的单向哈希存储,则更是如此。如果您需要再次显示密钥,则需要将用户的密钥以明文或对称加密方式存储。
通过拥有第二个信息或“秘钥”,您可以首先使用“键”查找用户或凭证,然后使用时序安全比较函数来检查“秘钥”的值。
以下是Python实现该功能的代码:
这个问题暴露在hmac
库中(可能还有其他库):
https://docs.python.org/3/library/hmac.html#hmac.compare_digest
需要注意的是,我认为这种攻击方式不会对在查找之前进行哈希或加密的值起作用,因为正在比较的值在输入字符串中每次更改一个字符时都会随机变化。我在这里找到了一个很好的解释。
存储API密钥的解决方案如下:
其中,我认为3是安全和便利之间的最佳平衡。在获取密钥时,我已经看到许多网站采用了这种方法。
此外,我邀请任何真正的安全专家批评此答案。我只是想把这个作为另一个讨论点。
最好在请求中只放置您的公钥,并使用您的私钥在本地签署请求;不需要发送其他内容。但有些人只将秘钥放在请求中。好吧,任何好的API都会使用一些传输安全机制,比如TLS(通常通过HTTPS)。但是这样您仍然将您的私钥暴露给服务器,增加了他们某种方式处理错误的风险(参见:GitHub和Twitter最近发现的密码记录漏洞)。理论上,HTTPS也同样安全,但总有实现缺陷存在。
但许多 - 实际上似乎大多数 - API要求您在请求中发送两个密钥,因为这比让用户自己签名容易得多;否则无法获得纯cURL示例!在这种情况下,将它们分开是毫无意义的。我想分离密钥只是为了以防将来改变API以利用它们。或者一些客户端库可能会更安全地执行。