无需移动应用用户身份验证即可保护私有 REST API 的最佳方式
Best way to secure Private REST API without user authentication for mobile app
我正在为我的移动应用制作一些 Restful API。
APP和webserver之间的通信必须在REST中进行。这些 api 应该是私有的,只有我的应用程序才能调用它们以获得成功的结果。
困难的是,我的应用程序不需要用户 ID 和密码,所以我不知道如何在没有基本用户身份验证的情况下限制移动应用程序的休息 API。
我认为的一个解决方案是嵌入某种硬编码字符串,这样当移动应用程序将使用 restful url 时,它们将通过 ssl 以加密格式传递该字符串。但我知道这似乎是一个非常糟糕的解决方案..
请提出在这种情况下最好的解决方案。
我建议在应用程序中创建一个复杂的令牌,由时间戳 + appId + 您可以在服务器上复制的任何其他值组成,并使用这些在每个请求的 header 中进行身份验证。
例如,您可以在您的数据库中创建一个虚拟 "user" 并将 deviceToken 存储在其中并将其用于您的算法。
我个人保留了一个API请求public,也就是时间戳getter,也就是returns服务器在300秒内使用的时间戳。
所以在每个请求之前,获取时间戳,并发送您创建的令牌,将其复制到服务器上,从而对请求进行身份验证。
普通黑客可以对应用进行逆向工程并复制您的令牌
看看基于哈希的消息认证码 (HMAC) 机制。
维基百科link:http://en.wikipedia.org/wiki/Hash-based_message_authentication_code
您的客户端(移动应用程序)将需要一个 public API 密钥来标识 REST 网络服务客户端和一个 private / 加密 密钥。 public API 密钥可以与 HTTP 请求一起发送。是public,大家都能看到。然而,私钥不应该与请求一起发送,并且应该只被服务器和客户端知道。该密钥用于生成散列消息,该消息将被发送到服务器。 HMAC 可以使用 SHA1 / MD5 算法生成,一条消息应该由服务器和客户端都知道的算法生成,最后是私钥。
你是对的,应用程序中嵌入的密钥可以通过数据包嗅探器或各种其他技术轻松检索。您可以按照以下说明解决此问题。
- 客户端(您的应用)将调用 required API
- 服务器将拒绝它,但作为响应,它会发送一个包含随机散列的字符串 (=challenge)。
- 客户端将该字符串与其他字符串 (=password)(已嵌入到应用程序中)结合使用以生成新的哈希值 (=digest)
- 客户端将再次调用相同的 API,但这次使用新创建的摘要作为身份验证参数。
- 服务器将验证该摘要并继续
仅供参考:上述过程是被广泛接受的标准,被称为 Digest Authentication。如果您需要更多帮助,请向 Google 询问 "android http digest authentication"
你确实可以让逆向工程师的工作变得更难,但不能像 Nasir 所说的那样通过引入数学上的难题并相应地转换你的硬编码字符串来让它变得无懈可击。
这个怎么样。假设一个数字 A
在应用程序中硬编码。服务器发送两个数字 B
& P
(P 是一个大质数)。现在您可以使用 (A^B) % P
计算将由服务器验证的实际数量。您的应用现在使用 Server's Public Key
加密 (A^B)%P
的答案。服务器将使用其私钥对其进行解密,对其进行验证并发出一个带有过期时间的令牌(可能是 jwt)。然后您的应用程序和服务器可以使用该令牌进行通信。您可以在应用程序启动时执行一次计算并存储令牌以供进一步使用。
我正在为我的移动应用制作一些 Restful API。
APP和webserver之间的通信必须在REST中进行。这些 api 应该是私有的,只有我的应用程序才能调用它们以获得成功的结果。
困难的是,我的应用程序不需要用户 ID 和密码,所以我不知道如何在没有基本用户身份验证的情况下限制移动应用程序的休息 API。
我认为的一个解决方案是嵌入某种硬编码字符串,这样当移动应用程序将使用 restful url 时,它们将通过 ssl 以加密格式传递该字符串。但我知道这似乎是一个非常糟糕的解决方案..
请提出在这种情况下最好的解决方案。
我建议在应用程序中创建一个复杂的令牌,由时间戳 + appId + 您可以在服务器上复制的任何其他值组成,并使用这些在每个请求的 header 中进行身份验证。
例如,您可以在您的数据库中创建一个虚拟 "user" 并将 deviceToken 存储在其中并将其用于您的算法。
我个人保留了一个API请求public,也就是时间戳getter,也就是returns服务器在300秒内使用的时间戳。
所以在每个请求之前,获取时间戳,并发送您创建的令牌,将其复制到服务器上,从而对请求进行身份验证。
普通黑客可以对应用进行逆向工程并复制您的令牌
看看基于哈希的消息认证码 (HMAC) 机制。
维基百科link:http://en.wikipedia.org/wiki/Hash-based_message_authentication_code
您的客户端(移动应用程序)将需要一个 public API 密钥来标识 REST 网络服务客户端和一个 private / 加密 密钥。 public API 密钥可以与 HTTP 请求一起发送。是public,大家都能看到。然而,私钥不应该与请求一起发送,并且应该只被服务器和客户端知道。该密钥用于生成散列消息,该消息将被发送到服务器。 HMAC 可以使用 SHA1 / MD5 算法生成,一条消息应该由服务器和客户端都知道的算法生成,最后是私钥。
你是对的,应用程序中嵌入的密钥可以通过数据包嗅探器或各种其他技术轻松检索。您可以按照以下说明解决此问题。
- 客户端(您的应用)将调用 required API
- 服务器将拒绝它,但作为响应,它会发送一个包含随机散列的字符串 (=challenge)。
- 客户端将该字符串与其他字符串 (=password)(已嵌入到应用程序中)结合使用以生成新的哈希值 (=digest)
- 客户端将再次调用相同的 API,但这次使用新创建的摘要作为身份验证参数。
- 服务器将验证该摘要并继续
仅供参考:上述过程是被广泛接受的标准,被称为 Digest Authentication。如果您需要更多帮助,请向 Google 询问 "android http digest authentication"
你确实可以让逆向工程师的工作变得更难,但不能像 Nasir 所说的那样通过引入数学上的难题并相应地转换你的硬编码字符串来让它变得无懈可击。
这个怎么样。假设一个数字 A
在应用程序中硬编码。服务器发送两个数字 B
& P
(P 是一个大质数)。现在您可以使用 (A^B) % P
计算将由服务器验证的实际数量。您的应用现在使用 Server's Public Key
加密 (A^B)%P
的答案。服务器将使用其私钥对其进行解密,对其进行验证并发出一个带有过期时间的令牌(可能是 jwt)。然后您的应用程序和服务器可以使用该令牌进行通信。您可以在应用程序启动时执行一次计算并存储令牌以供进一步使用。