简体   繁体   English

API 密钥和 OAuth 的客户端凭据流之间的安全区别是什么?

[英]What is the security difference between API Keys and the client credentials flow of OAuth?

Consider an API that a client accesses directly (machine to machine) and that doesn't require user-specific authentication.考虑一个客户端直接访问(机器到机器)并且不需要特定于用户的身份验证的 API。 The way I understand it, in client_credentials , the client must store a client_id and client_secret that it uses to acquire and refresh tokens.根据我的理解,在client_credentials ,客户端必须存储用于获取和刷新令牌的client_idclient_secret With an API key, the client just stores the key.使用 API 密钥,客户端只需存储密钥。 What makes OAuth more secure in this case?在这种情况下,是什么让 OAuth 更安​​全? It would appear to me that if the API key is never compromised, no attacker could pose as the intended client.在我看来,如果 API 密钥永远不会被泄露,那么攻击者就无法伪装成预期的客户端。 And if the API key is compromised, it is effectively the same as compromising the client_id and client_secret , which an attacker would be able to use to obtain tokens and access the data in the API, posing as the client.如果 API 密钥被泄露,它实际上与破坏client_idclient_secret ,攻击者可以使用它们来获取令牌并访问 API 中的数据,冒充客户端。

edit: clarified this is a machine-to-machine call编辑:澄清这是一个机器对机器的调用

TLDR; TLDR;

The difference comes down to direct access vs. delegated access .区别在于直接访问与委托访问

OAuth allows you to make delegated access. OAuth 允许您进行委托访问。 The benefits of delegated access don't change if there is a user involved or not.无论是否涉及用户,委派访问的好处都不会改变。 The same arguments that make the OAuth Authorization code flow attractive for user-to-machine access, apply to the OAuth Client credentials flow for machine-to-machine access.使 OAuth 授权代码流对用户到机器访问具有吸引力的相同论点,也适用于机器到机器访问的 OAuth 客户端凭据流。

Ask yourself, do you want the resource server to handle client credentials or not?问问自己,您是否希望资源服务器处理客户端凭据?

On confidential clients for machine-to-machine access, the cost of delegated access vs. direct access may very well outweigh the benefits.在用于机器对机器访问的机密客户端上,委派访问与直接访问的成本可能远远超过收益。 That's why so many APIs still use API keys.这就是为什么这么多 API 仍然使用 API 密钥的原因。 You'll have to decide that for your individual use case.您必须为您的个人用例决定。

Differences差异

In the OAuth client credentials flow, the client sends an access token to the resource server, which it got beforehand by the authorization server after presenting its client ID and secret.在 OAuth 客户端凭据流中,客户端向资源服务器发送访问令牌,授权服务器在提供其客户端 ID 和机密后预先获得该令牌。 The resource server never sees the client secret.资源服务器永远不会看到客户端机密。 With an API key, the client sends the key with every request.使用 API 密钥,客户端会随每个请求发送密钥。

OAuth adds an additional layer of indirection with the authorization server, such that the credentials themselves never get transmitted to the resource server. OAuth 为授权服务器添加了一个额外的间接层,这样凭据本身永远不会传输到资源服务器。 This allows the authorization server to give the client only access for a limited amount of time or with limited permissions, without ever needing to change the actual client credentials.这允许授权服务器仅在有限的时间内或以有限的权限授予客户端访问权限,而无需更改实际的客户端凭据。 It also allows to revoke access tokens without revoking the credentials themselves.它还允许在不撤销凭据本身的情况下撤销访问令牌。 For multiple instances of a client this allows you to revoke access for some but not all.对于客户端的多个实例,这允许您撤消某些但不是全部的访问权限。

Of course this all comes at the cost of a more complex implementation, and an additional roundtrip from the client to the authorization server.当然,这一切都以更复杂的实现以及从客户端到授权服务器的额外往返为代价。

I won't touch on transmission (URL, header, body, etc.) or format (random string, signed JWT, etc.), since these can be the same for access tokens just as for API keys.我不会涉及传输(URL、标题、正文等)或格式(随机字符串、签名的 JWT 等),因为这些对于访问令牌和 API 密钥来说是相同的。

Another, maybe not so obvious, advantage of OAuth is having a clear spec that libraries, documentation and discussions can be based on. OAuth 的另一个可能不那么明显的优势是有一个明确的规范,库、文档和讨论都可以以此为基础。 With direct access there is no single best practice and different people may understand different things when referring to direct access methods like API keys.直接访问没有单一的最佳实践,当提到 API 密钥等直接访问方法时,不同的人可能会理解不同的东西。

OAuth Client Credentials Flow OAuth 客户端凭据流

What is the security difference between API Keys and the client credentials flow of OAuth? API 密钥和 OAuth 的客户端凭据流之间的安全区别是什么?

OAuth client credentials flow is not meant to be used by public clients, just between machines. OAuth 客户端凭据流不打算由公共客户端使用,仅在机器之间使用。

From auth0.com/docs :来自auth0.com/docs

Client Credentials Flow客户凭证流

With machine-to-machine (M2M) applications, such as CLIs, daemons, or services running on your back-end, the system authenticates and authorizes the app rather than a user.通过在后端运行的机器对机器 (M2M) 应用程序(例如 CLI、守护程序或服务),系统会对应用程序而非用户进行身份验证和授权。 For this scenario, typical authentication schemes like username + password or social logins don't make sense.对于这种情况,用户名 + 密码或社交登录等典型的身份验证方案没有意义。 Instead, M2M apps use the Client Credentials Flow (defined in OAuth 2.0 RFC 6749, section 4.4), in which they pass along their Client ID and Client Secret to authenticate themselves and get a token.相反,M2M 应用程序使用客户端凭据流(在 OAuth 2.0 RFC 6749 的第 4.4 节中定义),在其中它们传递其客户端 ID 和客户端密钥以进行身份​​验证并获取令牌。

So, I am not sure what is your scenario, but I will assume in my reply that you are referring to public clients.所以,我不确定你的情况是什么,但我会在我的回复中假设你指的是公共客户。

If it is in the public client code, then it is public如果它在公共客户端代码中,则它是公共的

The way I understand it, in client_credentials, the client must store a client_id and client_secret that it uses to acquire and refresh tokens.根据我的理解,在 client_credentials 中,客户端必须存储用于获取和刷新令牌的 client_id 和 client_secret。

Yes, it needs to be stored in the client code for the client to be able to obtain the OAuth token.是的,它需要存储在客户端代码中,以便客户端能够获取 OAuth 令牌。

If you use the client_secret from a web app or mobile app you are making it public, therefore not a secret anymore.如果您使用来自 Web 应用程序或移动应用程序的client_secret ,您将其公开,因此不再是秘密。

Extracting secrets from public clients从公共客户端中提取机密

For example, in a web app all it takes to extract the client_secret is to hit F12 in the browser and search for it, thus how much time can this take?例如,在 Web 应用程序中,提取client_secret所需要的只是在浏览器中按F12并搜索它,那么这需要多长时间?

Now, in a mobile app, some may think it's secure because they are compiled into a binary but is almost as easy as it is in the browser, because we have several open-source tools that can help us with this task, like the MobSF framework, and on Linux, you can even achieve this with the strings command.现在,在移动应用程序中,有些人可能认为它是安全的,因为它们被编译成二进制文件,但几乎和在浏览器中一样简单,因为我们有几个开源工具可以帮助我们完成这项任务,例如 MobSF框架,在 Linux 上,您甚至可以使用strings命令实现这一点。 Using the MobSF to perform static binary analysis on the mobile app binary allows for anyone without hacking knowledge to easily extract the client_secret in minutes, just like I show in my article How to Extract an API key from a Mobile App with Static Binary Analysis :使用 MobSF 对移动应用程序二进制文件执行静态二进制分析,任何没有黑客知识的人都可以在几分钟内轻松提取client_secret ,就像我在我的文章如何使用静态二进制分析从移动应用程序中提取 API 密钥所示

The range of open source tools available for reverse engineering is huge, and we really can't scratch the surface of this topic in this article, but instead, we will focus in using the Mobile Security Framework(MobSF) to demonstrate how to reverse engineer the APK of our mobile app.可用于逆向工程的开源工具的范围非常广泛,我们无法在本文中触及该主题的皮毛,相反,我们将重点使用移动安全框架 (MobSF)来演示如何进行逆向工程我们的移动应用程序的 APK。 MobSF is a collection of open-source tools that present their results in an attractive dashboard, but the same tools used under the hood within MobSF and elsewhere can be used individually to achieve the same results. MobSF 是一个开源工具的集合,它们在一个有吸引力的仪表板中展示他们的结果,但是在 MobSF 和其他地方使用的相同工具可以单独使用来实现相同的结果。

So, the process of extracting the api-key in my article is the same you will use to extract the client_secret or any other string of your interest in the mobile app binary.因此,在我的文章中提取api-key的过程与在移动应用程序二进制文件中提取client_secret或您感兴趣的任何其他字符串的过程相同。

OAuth or API Key? OAuth 或 API 密钥?

What makes OAuth more secure in this case?在这种情况下,是什么让 OAuth 更安​​全? It would appear to me that if the API key is never compromised, no attacker could pose as the intended client.在我看来,如果 API 密钥永远不会被泄露,那么攻击者就无法伪装成预期的客户端。 And if the API key is compromised, it is effectively the same as compromising the client_id and client_secret, which an attacker would be able to use to obtain tokens and access the data in the API, posing as the client.如果 API 密钥被泄露,它实际上与破坏 client_id 和 client_secret 相同,攻击者可以使用它们来获取令牌并访问 API 中的数据,冒充客户端。

If used from a public client neither are secure, because if read my linked article, you understand by now how easy is to bypass an API Key or extract the client_secret and client_id .如果从公共客户端使用,两者都不安全,因为如果阅读我的链接文章,您现在就会了解绕过 API 密钥或提取client_secretclient_id是多么容易。

So, if your client is public you should not use the OAuth client credential flow, thus you need to go with the insecure API key approach or you can be more diligent and try to apply defence-in-depth approaches, but this will depend if the API clients are only web apps or mobile apps or both.因此,如果您的客户端是公开的,则不应使用 OAuth 客户端凭据流,因此您需要使用不安全的 API 密钥方法,或者您可以更加勤奋并尝试应用深度防御方法,但这取决于API 客户端只是 Web 应用程序或移动应用程序或两者兼而有之。

If your API clients are only web apps I invite you to read my answer to the question Secure API data from calls out of the app , especially the section dedicated to Defending the API Server.如果您的 API 客户端只是 Web 应用程序,我邀请您阅读安全 API 数据来自应用程序调用的问题的回答,特别是专门讨论保护 API 服务器的部分。

In the case the API clients are only mobile apps then I recommend you to read this answer I gave to the question How to secure an API REST for mobile app?如果 API 客户端只是移动应用程序,那么我建议您阅读我对如何为移动应用程序保护 API REST的问题给出的答案 , especially the sections Securing the API Server and A Possible Better Solution . ,尤其是保护 API 服务器可能的更好解决方案部分

On the other hand, if your API clients are both a web app and a mobile app I recommend you to apply the security measures more relevant to you from both answers linked above.另一方面,如果您的 API 客户端既是 Web 应用程序又是移动应用程序,我建议您应用上面链接的两个答案中与您更相关的安全措施。

Remember that security is always about adding as many layers of defences as you can afford or it's required by law.请记住,安全始终是在您负担得起或法律要求的范围内添加尽可能多的防御层。 Even in the past century, the castles were built with a lot of different security defence layers, thus this is nothing new to the digital era.即使在上个世纪,城堡也建立了许多不同的安全防御层,因此这对数字时代来说并不是什么新鲜事。

Do You Want To Go The Extra Mile?你想走得更远吗?

In any response to a security question I always like to reference the excellent work from the OWASP foundation.在对安全问题的任何回答中,我总是喜欢参考 OWASP 基金会的出色工作。

For APIS用于APIS

OWASP API Security Top 10 OWASP API 安全前 10 名

The OWASP API Security Project seeks to provide value to software developers and security assessors by underscoring the potential risks in insecure APIs, and illustrating how these risks may be mitigated. OWASP API 安全项目旨在通过强调不安全 API 中的潜在风险并说明如何减轻这些风险来为软件开发人员和安全评估人员提供价值。 In order to facilitate this goal, the OWASP API Security Project will create and maintain a Top 10 API Security Risks document, as well as a documentation portal for best practices when creating or assessing APIs.为了实现这一目标,OWASP API 安全项目将创建和维护一个前 10 个 API 安全风险文档,以及创建或评估 API 时最佳实践的文档门户。

For Mobile Apps对于移动应用程序

OWASP Mobile Security Project - Top 10 risks OWASP 移动安全项目 - 十大风险

The OWASP Mobile Security Project is a centralized resource intended to give developers and security teams the resources they need to build and maintain secure mobile applications. OWASP 移动安全项目是一个集中资源,旨在为开发人员和安全团队提供构建和维护安全移动应用程序所需的资源。 Through the project, our goal is to classify mobile security risks and provide developmental controls to reduce their impact or likelihood of exploitation.通过该项目,我们的目标是对移动安全风险进行分类并提供开发控制以减少其影响或被利用的可能性。

OWASP - Mobile Security Testing Guide : OWASP - 移动安全测试指南

The Mobile Security Testing Guide (MSTG) is a comprehensive manual for mobile app security development, testing and reverse engineering.移动安全测试指南 (MSTG) 是移动应用安全开发、测试和逆向工程的综合手册。

For Web Apps对于 Web 应用程序

The Web Security Testing Guide :网络安全测试指南

The OWASP Web Security Testing Guide includes a "best practice" penetration testing framework which users can implement in their own organizations and a "low level" penetration testing guide that describes techniques for testing most common web application and web service security issues. OWASP Web 安全测试指南包括一个“最佳实践”渗透测试框架,用户可以在他们自己的组织中实施该框架和一个“低级”渗透测试指南,它描述了测试最常见的 Web 应用程序和 Web 服务安全问题的技术。

With client credential flow your Client Id and Client Secret are sent to the authorization server to get back an access token.通过客户端凭据流,您的客户端 ID 和客户端密钥将发送到授权服务器以取回访问令牌。 For all subsequent request to the API/resource servers, you pass the access token and not the client credentials themselves.对于对 API/资源服务器的所有后续请求,您传递访问令牌而不是客户端凭据本身。 The access token is usually a JWT, which is a set of encoded claims including the token expiry ( exp ), not before ( nbf ), token issuer ( iss ), authorized party ( azp ), roles, permissions, etc.访问令牌通常是一个 JWT,它是一组编码声明,包括令牌到期 ( exp )、不在之前 ( nbf )、令牌颁发者 ( iss )、授权方 ( azp )、角色、权限等。

This has a number of advantages over a simple API Key approach.与简单的 API Key 方法相比,这具有许多优点。 eg例如

  • If the access token (which is included in requests to the API/resource server) is compromised, it's only valid until it expires (which is usually a day for M2M tokens).如果访问令牌(包含在对 API/资源服务器的请求中)被泄露,则它仅在到期前有效(对于 M2M 令牌通常是一天)。 If an API Key is compromised, it can be used indefinitely eg until it's explicitly blocked by the API/resource server.如果 API 密钥被泄露,它可以无限期地使用,例如直到它被 API/资源服务器明确阻止。
  • JWT access tokens contains a number of claims that can be used for fine grained authorization eg roles, permissions, grant type, authorized party etc. An API Key is generally all or nothing when it comes to auth. JWT 访问令牌包含许多可用于细粒度授权的声明,例如角色、权限、授权类型、授权方等。 API 密钥在涉及身份验证时通常是全有或全无。
  • You machine tokens can get validated and authorized on the API/resource servers the same way as your user tokens, so you don't end up with multiple auth implementations on the back-end.您的机器令牌可以在 API/资源服务器上以与您的用户令牌相同的方式获得验证和授权,因此您不会在后端获得多个身份验证实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用OAuth2客户端凭据流保护用PHP编写的REST API - Securing a REST API written in PHP with OAuth2 client credentials flow lepture / authlib OAuth2 Client和Session有什么区别? - What is the difference between lepture/authlib OAuth2 Client and Session? 适用于JavaScript API客户端的OAuth2流程 - Appropriate OAuth2 flow for JavaScript API client hive jdbc 客户端和 hive Metastore java api 有什么区别? - What is the difference between the hive jdbc client and the hive metastore java api? Spotify API - Kotlin 中的客户端凭证流与 Retrofit 不起作用 - Spotify API - Client Credentials Flow in Kotlin with Retrofit doesnt work 为什么要使用Client Credentials流程? - Why use Client Credentials flow? 结合API的oAuth 2.0客户端凭据和资源所有者密码凭据授予类型? - Combine oAuth 2.0 Client Credentials and Resource Owner Password Credentials Grant Types for API? 将oAuth与资源所有者密码凭证授予一起使用时正确的流程是什么? - What is the correct flow when using oAuth with the Reso​urce Owners Password​s Credentials Grant​ API和程序包有什么区别? - what is the difference between an API and a package? Demon和API有什么区别? - What is difference between Demon and API?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM