为什么要使用API​​密钥和机密?


93

我遇到了许多API,这些API为用户提供了API密钥秘密。但是我的问题是:两者之间有什么区别?

在我眼中,一把钥匙就足够了。说我有一把钥匙,只有我和服务器知道。我使用此密钥创建HMAC哈希并进行API调用。在服务器上,我们再次创建HMAC哈希并将其与发送的哈希进行比较。如果相同,则对呼叫进行身份验证。

那么为什么要使用两个键呢?

编辑:还是该API密钥用于查找API机密?


Answers:


45

秘密密钥加密技术依赖于使用相同的密钥来编码,然后再对消息进行解码。因此,只有知道“秘密”的人才能阅读该消息。

RSA安全性基于2个匹配密钥。每个用户都有一个公共密钥,每个人都可以(应该)知道它。还有一个只有用户应该知道的私钥。用公钥加密的消息只能用私钥解密,反之亦然。

因此,如果我想向您发送一条只有您可以阅读的消息,我(从网络中)会获得您的公共密钥,使用该密钥对消息进行加密,并且您是唯一可以解密它的人。

或者,如果我想向您证明我已发送邮件,则可以使用私钥对邮件进行加密,然后(以公开文本或另一封邮件的形式)告诉您邮件是如何加密的。然后,您可以使用我的公共密钥解密该消息,如果该消息可读,那么您就知道它来自我。

这种加密形式相当耗费计算机资源,因此有时要做的是使用RSA技术加密一次性的“秘密密钥”,然后使用秘密密钥加密消息的其余部分,然后以第二种方式加密我的签名。然后,您可以逆转此过程,以便如果邮件和签名可读,则只有您自己可以阅读,并且可以确保我发送了邮件。

要么

您可以访问此链接以获取更多详细说明。

API密钥和秘密密钥如何工作?


9
很好的答案,但是当我在Facebook或Gmail等中使用API​​机密和密钥时,我绝对不需要加密或散列任何内容。在这些情况下,API机密和密钥的意义何在?
Quintonn '16

2
以Facebook为例,有两种方案可以使用app_secret。第一个不需要哈希。它主要用于防止您的重定向URL被劫持。如果Facebook直接将访问令牌发送到重定向URL,则用户登录并授予您的应用访问权限后,您将无法验证访问令牌是否来自Facebook。我可以将自己的访问令牌发布到您的重定向URL上,并执行来自您的api的facebook操作。相反,facebook将代码发送到重定向URL。然后,api将代码交换为实际的访问令牌。
瑞安·托马斯

2
在后一部分中,将代码交换为实际的访问令牌,facebook希望您的api用签名验证其身份。在这种情况下,他们不需要公共密钥加密来签名,他们只是信任您以将应用程序的秘密保密为真正的秘密,并将其用作签名。对我而言,不继续使用单向函数来生成签名似乎总是很愚蠢,但我认为它们有诸如为直接使用应用程序机密而解决的性能之类的原因。
瑞安·托马斯

在第二个用例中,您确实使用了加密哈希。在拥有实际的access_token以开始与Facebook进行交互之后,您可能需要额外的安全性以防止您的应用程序被假冒。在Facebook应用程序控制台中,您可以打开一项功能,该功能要求您的应用程序发出的每个Facebook api请求都包括访问令牌之外的签名。我只是在猜测他们的动机,但我认为目前他们不希望您在每次请求中都反复发送app_secret作为签名。发送的次数越多,app_secret受到破坏的机会就越大。
瑞安·托马斯

1
我想,既然您选择了此额外的安全功能,您还做出了某种决定,以允许Facebook额外的性能开销,即在其末端通过加密哈希调用来验证您的签名。无论如何,在这种情况下,您需要通过Facebook api请求传递两个值。access_token和一个名为appsecret_proof的值用作您的签名。应用秘密证明是通过使用app_secret作为密钥对access_token进行加密哈希生成的。
瑞安·托马斯

55

您需要两个单独的键,一个告诉他们您是谁,另一个则证明您是您所说的人

“密钥”是您的用户ID,“秘密”是您的密码。他们只使用“密钥”和“秘密”术语,因为这就是它们的实现方式。


1
如果您通过https通讯怎么办?那么用一些秘密密钥加密消息有什么意义呢?
kamuniaft

6
重点始终是降低风险。如果https通讯受到威胁,则可以读取您的请求的攻击者将无法伪造新请求。如果您的API要对猫的照片进行排名,没什么大不了的,如果它是一种付款API,则最好具有多层安全性:)
Yall

我想它的目的是两个单独的密钥,因为单个客户端应用程序的不同用户可以具有不同的秘密,否则,如果他们都具有相同的秘密,那么拥有密钥就没有用。对?
亲爱的

这些API为什么不Bearer:为此使用身份验证?您将在那里有一个ID和一个密码。
Stefan Haberl

7

简单的答案,如果我理解正确的话...

如果您使用API​​密钥进行加密,则服务如何知道与谁联系的人?他们将如何解密该消息?

您使用API​​密钥来说明您的身份,这就是您以纯文本格式发送的内容。您不会发送给任何人的SECRET密钥。您只需将其用于加密即可。然后,您发送加密的消息。您不会发送用于加密的密钥,否则会达到目的。


你做。您将api密钥发送到服务器。因此,这意味着您正在向可能拦截与服务器通信的任何人提供该值。
ancajic

我见过的几乎每个API都将密钥和机密都发送到了服务器。与服务器的连接在理论上具有相同的安全级别。但是我从不向服务器以外的任何人提供任何服务。
sudo

我从未见过发送secret纯文本。你能给我一个链接吗?我看到的是secret用来加密一些数据的。连同加密的数据一起发送,apiKey以便服务器知道如何解密数据。
ancajic

twilio.com/docs/sms/tutorials/…nexmo.github.io/Quickstarts/sms/send是我看到的促使我在StackOverflow上进行搜索的示例。
sudo

Twilio并不完全使用这些术语。但是Nexmo肯定是...但是,快速浏览之后,似乎他们只是在调用数据secretapiKey而实际上他们在做什么usernamepassword。这是完全不同的事情……
ancajic

3

有答案说明秘密和(公共)密钥是什么。他们给他们一个令人困惑的名字,是一个公私钥对。但是没有人说为什么这些API要求同时使用,许多API只给您一个秘密!我也从未见过任何API的文档解释为什么它们有两个键,所以我能做的最好的就是推测...

最好只在请求中放入公钥,然后用私钥在本地签署请求;不需要再发送任何内容。但是有些人只是在请求中包含秘密而逃脱了。好的,任何好的API都会使用某些传输安全性,例如TLS(通常通过HTTPS)。但是您仍然以这种方式将私钥暴露给服务器,从而增加了以某种方式误处理私钥的风险(请参阅:GitHub和Twitter最近发现的密码记录错误)。从理论上讲,HTTPS同样安全,但是始终存在实现缺陷。

但实际上,似乎很多API都可以让您在请求中发送两个密钥,因为这比让人们自己签名容易得多。否则不能有纯cURL示例!在这种情况下,将它们分开是没有意义的。我猜想单独的键只是为了防止它们以后更改API以利用它们。或有些客户端库可能更安全。


0

尽管这是Marcus Adams回答的扩展,但我没有看到的一件事是,如果存在定时攻击的可能性,则不应使用一条信息来识别和验证用户,这可能使用响应时间的差异来猜测字符串比较能达到的程度。

如果您使用的系统使用“密钥”来查找用户或凭据,则可以通过发送数千个请求并检查数据库查找(或不查找)所花费的时间来逐步猜测该信息查找)一条记录。如果“密钥”以明文存储而不是密钥的单向哈希,则尤其如此。如果需要能够再次向用户显示密钥,则希望将其密钥存储为纯文本格式或对称加密。

通过获取第二条信息或“秘密”信息,您可以首先使用“密钥”查找用户或凭证,这可能容易受到定时攻击,然后使用定时安全比较功能来检查“秘密”。

这是该函数的Python实现:

https://github.com/python/cpython/blob/cd8295ff758891f21084a6a5ad3403d35dda38f7/Modules/_operator.c#L727

它在hmaclib(可能还有其他)中公开:

https://docs.python.org/3/library/hmac.html#hmac.compare_digest


这里要注意的一件事是,我认为这种攻击不会对在查找之前经过哈希处理或加密的值起作用,因为每次输入字符串中的字符更改时,被比较的值都会随机更改。我在这里找到了很好的解释。

存储API密钥的解决方案如下:

  1. 使用单独的密钥和机密,使用密钥来查找记录,并使用定时安全的比较来检查机密。这使您可以向用户显示密钥和机密。
  2. 使用单独的密钥和机密,对机密使用对称的确定性加密,并对加密后的机密进行常规比较。这使您可以再次向用户显示密钥和机密,并且可以免去执行定时安全比较的麻烦。
  3. 使用单独的密钥和密钥,显示密钥,对其进行哈希处理并存储,然后对哈希后的密钥进行常规比较。这消除了使用双向加密的必要性,并具有在系统受到威胁时保持机密安全的附加好处。不利的一面是您无法再次向用户显示机密。
  4. 使用单个密钥,向用户展示一次,对其进行哈希处理,然后对哈希或加密的密钥进行常规查找。这使用一个键,但是无法再次显示给用户。如果系统受到威胁,则可以确保密钥安全。
  5. 使用单个密钥,向用户显示一次,对其进行加密,然后对加密的秘密进行常规查找。可以再次显示给用户,但是如果密钥遭到破坏,则会以使密钥易受攻击为代价。

其中,我认为3是安全性和便利性的最佳平衡。在获取密钥时,我已经在许多网站上实现了此功能。

另外,我邀请任何实际的安全专家来批评这个答案。我只是想把这个作为另一个讨论重点。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.