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

EsT*_*eGe 77 security authentication api api-key secret-key

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

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

那为什么要用两把钥匙?

编辑:或者是用于查找API密钥的API密钥?

Mar*_*ams 48

你需要两个独立的钥匙,一个告诉他们你是谁,另一个证明你就是你说的那个人.

"密钥"是您的用户ID,"密码"是您的密码.他们只是使用"密钥"和"秘密"术语,因为他们是如何实现它的.

  • 关键在于降低风险.如果https通信遭到破坏,那么可以读取您请求的攻击者将无法伪造新的请求.如果您的API即将对猫的图片进行排名,没什么大不了的,如果它是支付API,您最好有多层安全性:) (4认同)
  • 最后一段应为粗体 (2认同)
  • 如果您通过 https 进行通信呢?那么用一些秘密密钥加密你的消息有什么意义呢? (2认同)

SAL*_*MAN 39

秘密密钥密码术依赖于使用相同的密钥进行编码,然后对消息进行解码.因此,只有那些知道"秘密"的人才能阅读该消息.

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

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

或者,如果我想向您证明我发送了一条消息,我可以使用我的私钥加密消息,告诉您(在开放文本或其他消息中)它是如何加密的.然后你可以使用我的公钥解密消息,如果它变得可读,你知道它来自我.

这种加密形式是计算机密集型的,因此有时会采用RSA技术加密一次性"密钥",然后用密钥加密其余的消息,然后以第二种方式加密我的签名.然后,您可以反转此过程,因此如果消息和签名是可读的,您和只有您可以阅读它并确保我发送了消息.

要么

您可以访问此链接以获取更详细的说明.

API密钥和密钥如何工作?

  • 很好的答案,但当我使用Facebook或Gmail等API秘密和密钥时,我不得加密或散列任何东西.在这些情况下,API秘密和密钥的重点是什么? (6认同)
  • 我很惊讶这被选为接受的答案。该问题询问 API 密钥和秘密密钥,我认为它们与公钥加密或加密没有任何关系。马库斯·亚当斯 (Marcus Adams) 的那篇文章确实是这个问题的答案。 (3认同)
  • 以Facebook为例,有两种情况可以使用app_secret。第一个不需要哈希。它主要用于防止您的重定向URL被劫持。如果Facebook直接将访问令牌发送到重定向URL,则用户登录并授予您的应用访问权限后,您将无法验证访问令牌是否来自Facebook。我可以将自己的访问令牌发布到您的重定向URL上,并执行来自您的api的facebook操作。相反,facebook将代码发送到重定向URL。然后,api将代码交换为实际的访问令牌。 (2认同)
  • 在后一部分中,将代码交换为实际的访问令牌,facebook希望您的api用签名验证其身份。在这种情况下,他们不需要公共密钥加密来签名,他们只是信任您以将应用程序的秘密保密为真正的秘密,并将其用作签名。对我而言,不继续使用单向函数来生成签名似乎总是很愚蠢,但我认为它们有诸如为直接使用应用程序机密而解决的性能之类的原因。 (2认同)

kbu*_*lds 11

我在这里没有看到提到的一件事是,尽管它是马库斯·亚当斯答案的延伸,但如果存在定时攻击的可能性,您不应该使用单条信息来识别和验证用户,这可以使用响应时间的差异来猜测字符串比较的程度。

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

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

下面是该函数的 Python 实现:

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

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

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


这里需要注意的一件事是,我认为这种攻击不适用于在查找之前进行散列或加密的值,因为每次输入字符串中的字符发生变化时,所比较的值都会随机变化。我在这里找到了一个很好的解释。

存储 API 密钥的解决方案将是:

  1. 使用单独的密钥和秘密,使用密钥查找记录,并使用定时安全比较来检查秘密。这允许您再次向用户显示密钥和秘密。
  2. 使用单独的密钥和秘密,对秘密使用对称、确定性加密,并对加密的秘密进行正常比较。这使您可以再次向用户显示密钥和秘密,并且可以使您不必实施时间安全的比较。
  3. 使用单独的密钥和秘密,显示秘密,散列并存储它,然后对散列秘密进行正常比较。这消除了使用双向加密的必要性,并且具有在系统遭到破坏时确保您的秘密安全的额外好处。它的缺点是您无法再次向用户显示秘密。
  4. 使用单个密钥,将其显示给用户一次,对其进行散列,然后对散列或加密的密钥进行正常查找。这使用单个密钥,但无法再次向用户显示。具有在系统遭到破坏时保持密钥安全的优点。
  5. 使用单个密钥,将其显示给用户一次,对其进行加密,并对加密的秘密进行正常查找。可以再次向用户显示,但代价是如果系统受到损害,密钥就会容易受到攻击。

其中,我认为3是安全性和便利性之间最好的平衡。我在许多网站上看到发放密钥时都采用了这种做法。

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


sud*_*udo 8

有一些答案解释了秘密和(公共)密钥是什么。这是一个公钥-私钥对,他们给它起了令人困惑的名称。但没有人说为什么 API 需要两者,而且许多 API 只给你一个秘密!我也从未见过任何 API 文档解释为什么它们有两个密钥,所以我能做的最好的就是推测......

\n\n

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

\n\n

但许多 \xe2\x80\x93 实际上大多数 \xe2\x80\x93 API 都让你在请求中发送两个密钥,因为这比让人们自己签名更容易;否则就不可能有纯 cURL 示例!在这种情况下,将它们分开是没有意义的。我想单独的密钥只是为了以防万一他们稍后更改 API 以利用它们。或者有些人有一个客户端库,可以以更安全的方式做到这一点。

\n


anc*_*jic 5

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

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

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