OAuth2 客户端 ID 和客户端密钥的安全性

Posted

技术标签:

【中文标题】OAuth2 客户端 ID 和客户端密钥的安全性【英文标题】:Security of OAuth2 Client Id and Client Secret 【发布时间】:2017-11-16 14:36:55 【问题描述】:

我正在开发一个通过 OAuth2 和 Spring 保护的 REST API,它将在 android 应用程序(客户端)中使用。为了访问我的 API 的任何端点,需要 OAuth2 访问令牌并通过 Authorization Header 以类似于以下方式移交给端点:

“授权”-“这里的承载访问令牌”

为了获取访问令牌,必须提供用户名和密码,以及客户端 ID 和客户端密码(它们代表 Android 应用)。 clientID 和 client secret 以类似这样的方式通过 Authorization Header 交给 token 端点,由 Spring 指定:

“授权”-“基本 clientId:clientSecret”

如果客户端 ID 和客户端密码与服务器上定义的客户端匹配,并且如果用户存在且密码正确,则返回访问令牌和刷新令牌。

现在我的问题是如何将我的 clientId 和客户端密码安全地存储在 Android 应用程序中,以确保对我的应用程序进行逆向工程的人无法访问它们?

另外,如果我要开发 ios 应用程序(第二个客户端),使用与安全 POV 不同的 clientID 和客户端密码是否明智?

【问题讨论】:

您的客户端是公共客户端,不需要客户端密码,因为您无法隐藏密码。另请参阅:***.com/a/43391526/5277820 和 ***.com/questions/44044528/…。 【参考方案1】:

你不能——即使有办法,我仍然可以检查线路上的有效负载以确定值。请参阅OAuth 2.0 for Native Apps 的第 8.5 节

作为分发给多个用户的应用程序的一部分静态包含的秘密不应被视为机密秘密,因为一个用户可能会检查他们的副本并了解共享的秘密。出于这个原因,以及 [RFC6819] 第 5.3.1 节中所述的原因,不建议授权服务器要求使用共享密钥对公共本机应用程序客户端进行客户端身份验证,因为除了客户端身份验证之外,这几乎没有价值 已由“client_id”请求参数提供。

您的客户端 id/secret 参数只是提供发出请求的应用程序的身份,因此建议您为 iOS 应用程序创建不同的客户端,无论是从安全隔离的角度来看 + 对于任何您想收集有关应用程序使用情况的分析(例如,“您通过客户端 ID 检索了多少次登录尝试?”等)

但是,攻击者可能会对您的设置进行逆向工程,获取您的客户端 ID + 密码,然后开始使用用户名/密码组合攻击您的令牌端点,以尝试暴力破解您的应用程序。如果端点接受这些值并返回成功/失败代码,这对于试图破坏您的系统的人来说是一个有用的攻击向量。

目前推荐的方法是使用“授权码流”

在原生应用中授权用户的当前最佳做法是 在外部用户代理(通常是浏览器)中执行 OAuth 授权请求,而不是在嵌入式用户代理(例如使用 Web 视图实现的用户代理)中。

以前原生应用通常使用嵌入式 用于 OAuth 的用户代理(通常使用 Web 视图实现) 授权请求。这种方法有很多缺点, 包括能够复制用户凭据的主机应用程序和 cookie,并且用户需要在每个 应用程序。有关使用嵌入式的更深入分析,请参见第 8.12 节 OAuth 的用户代理。”

查看AppAuth for Android了解更多信息,

【讨论】:

以上是关于OAuth2 客户端 ID 和客户端密钥的安全性的主要内容,如果未能解决你的问题,请参考以下文章

如何生成 OAuth 2 客户端 ID 和密钥

如何生成 OAuth 2 客户端 ID 和密钥

OAuth2.0笔记

Google文档是否已过时?

OAuth2 的客户端 JS 库如何维护安全认证?

仅具有客户端凭据的 Spring 安全端点(基本)