在 React Native 中存储密钥最安全的方式是什么 [英] What is the most secure way store keys in React Native

查看:138
本文介绍了在 React Native 中存储密钥最安全的方式是什么的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

提前感谢您的帮助.

我正在使用 React Native 和 Node.js 为我的公司交付产品.

我已经在后端设置了检索密码、验证密码并使用令牌响应的步骤.唯一的问题是 - 我在前端(移动应用程序)上使用的要由后端验证的密码是硬编码的.

我的问题是:

我应该如何安全地将此密码存储在移动应用程序上,以免被黑客窃取并用于破坏后端?

我目前的研究.

嵌入在strings.xml中

隐藏在源代码中

隐藏在 BuildConfig 中

使用混淆器

伪装/加密字符串

隐藏在本地库中

通常,OAuth 向客户端提供安全委托访问".代表资源所有者服务器资源.它指定了资源所有者授权第三方访问其服务器资源而不共享其凭据的过程.OAuth 专为与超文本传输​​协议 (HTTP) 一起使用而设计,本质上允许授权服务器在资源所有者的批准下将访问令牌颁发给第三方客户端.然后第三方使用访问令牌访问资源服务器托管的受保护资源.

OpenID 连接

OpenID Connect 1.0 是 OAuth 2.0 协议之上的一个简单身份层.它允许客户端根据授权服务器执行的身份验证来验证最终用户的身份,并以可互操作和类似 REST 的方式获取有关最终​​用户的基本配置文件信息.

虽然用户身份验证可以让 API 服务器知道正在使用该 API,但它不能保证请求来自您期望的WHAT,原始版本的移动应用.

现在我们需要一种方法来识别什么正在调用 API 服务器,而这里的事情变得比大多数开发人员想象的更棘手.WHAT 是向 API 服务器发出请求的东西.它真的是移动应用程序的真实实例,还是机器人、自动化脚本或攻击者使用 Postman 之类的工具手动浏览 API 服务器?

令您惊讶的是,您最终可能会发现,它可能是合法用户之一,使用重新打包的移动应用版本或试图游戏化并利用应用提供的服务的自动化脚本.

>

好吧,为了确定什么,开发人员倾向于求助于 API 密钥,通常他们在移动应用程序的代码中对其进行了硬编码.一些开发人员加倍努力并在移动应用程序中在运行时计算密钥,因此它成为运行时秘密,而不是将静态秘密嵌入代码中的前一种方法.

以上文章摘自我写的一篇文章,标题为为什么您的移动应用需要一个 API 密钥?,您可以阅读全文这里,这是 API 密钥系列文章的第一篇.

移动应用认证

使用移动应用证明解决方案将使 API 服务器知道什么正在发送请求,从而允许仅响应来自真正移动应用的请求,同时拒绝来自不安全的所有其他请求来源.

移动应用证明服务的作用是在运行时保证您的移动应用没有被篡改,没有在有根设备中运行,也没有成为中间人攻击的目标.这是通过在后台运行 SDK 来完成的,该 SDK 将与在云中运行的服务进行通信,以证明正在运行的移动应用程序和设备的完整性.云服务还会验证在与 API 服务器握手时提供给移动应用程序的 TLS 证书确实与用于移动应用程序的原始和正版 API 服务器相同,而不是来自中间人攻击的证书.

在成功证明移动应用程序完整性后,系统会发出一个短期存在的 JWT 令牌,并使用只有 API 服务器和云中的移动应用程序证明服务知道的秘密进行签名.如果移动应用认证失败,JWT 令牌会使用 API 服务器不知道的秘密进行签名.

现在,应用程序必须随每个 API 调用发送请求标头中的 JWT 令牌.这将允许 API 服务器仅在可以验证 JWT 令牌中的签名和到期时间时才提供请求,并在验证失败时拒绝它们.

一旦移动应用证明服务使用的秘密不被移动应用知道,即使应用被篡改、在有根设备中运行或通过连接进行通信,也无法在运行时对其进行逆向工程正在成为中间人攻击的目标.

因此,此解决方案适用于没有误报的阳性检测模型,因此不会阻止合法用户同时阻止坏人.

<块引用>

当讨厌的黑客窃取密钥并不当使用它们时,您有什么建议可以保护世界(React-Native 应用程序)免受黑客攻击?

我认为您应该使用移动应用证明解决方案,如果您拥有相关专业知识,您可以自己推出该解决方案,或者您可以使用已经存在的解决方案作为 Approov(我在这里工作),为多个平台提供 SDK,包括 iOS、Android、React Native 等.集成还需要对 API 服务器代码进行少量检查,以验证云服务发布的 JWT 令牌.此检查对于 API 服务器来说是必要的,以便能够决定提供哪些请求以及拒绝哪些请求.

总结

<块引用>

我希望能够在应用程序中存储密钥,以便我可以验证用户并允许他们访问后端的资源.但是,我不知道确保用户/业务安全的最佳行动计划是什么.

不要走这条在移动应用程序中存储密钥的路线,因为您已经知道,通过您的广泛研究,它们可以被绕过.

而是将移动证明解决方案与 OAUTH2 或 OpenID 连接结合使用,您可以将其与移动应用证明令牌绑定.可以在 这篇文章 用于检查端点 /forms 中的自定义负载声明.

走得更远

OWASP 移动安全项目 - 十大风险

<块引用>

OWASP 移动安全项目是一个集中式资源,旨在为开发人员和安全团队提供构建和维护安全移动应用程序所需的资源.通过该项目,我们的目标是对移动安全风险进行分类并提供开发控制以减少其影响或被利用的可能性.

Thanks for your help in advance.

I'm using React Native and Node.js to deliver a product for my company.

I've setup the steps on the backend to retrieve a password, validate it and respond with a token. The only problem is - the password I use on the front end (mobile app) to be validated by the back end is hardcoded.

My question is:

How should I securely store this password on the mobile app so that it can not be sniffed out by a hacker and used to compromise the backend?

My research so far.

Embedded in strings.xml

Hidden in Source Code

Hidden in BuildConfigs

Using Proguard

Disguised/Encrypted Strings

Hidden in Native Libraries

http://rammic.github.io/2015/07/28/hiding-secrets-in-android-apps/

These methods are basically useless because hackers can easily circumnavigate these methods of protection.

https://github.com/oblador/react-native-keychain

Although this may obfuscate keys, these still have to be hardcoded. Making these kind of useless, unless I'm missing something.

I could use a .env file https://github.com/luggit/react-native-config

Again, I feel like the hacker can still view secret keys, even if they are saved in a .env

I want to be able to store keys in the app so that I can validate the user an allow them to access resources on the backend. However, I don't know what the best plan of action is to ensure user/business security.

What suggestions do you have to protect the world (react- native apps) from pesky hackers, when they're stealing keys and using them inappropriately?

解决方案

Your Question

I've setup the steps on the backend to retrieve a password, validate it and respond with a token. The only problem is - the password I use on the front end (mobile app) to be validated by the back end is hardcoded.

My question is:

How should I securely store this password on the mobile app so that it can not be sniffed out by a hacker and used to compromise the backend?

The cruel truth is... you can't!!!

It seems that you already have done some extensive research on the subject, and in my opinion you mentioned one effective way of shipping your App with an embedded secret:

Hidden in Native Libraries

But as you also say:

These methods are basically useless because hackers can easily circumnavigate these methods of protection.

Some are useless and others make reverse engineer the secret from the mobile app a lot harder. As I wrote here, the approach of using the native interfaces to hide the secret will require expertise to reverse engineer it, but then if is hard to reverse engineer the binary you can always resort to a man in the middle (MitM) attack to steel the secret, as I show here for retrieving a secret that is hidden in the mobile app binary with the use of the native interfaces, JNI/NDK.

To protect your mobile app from a MitM you can employ Certificate Pinning:

Pinning is the process of associating a host with their expected X509 certificate or public key. Once a certificate or public key is known or seen for a host, the certificate or public key is associated or 'pinned' to the host. If more than one certificate or public key is acceptable, then the program holds a pinset (taking from Jon Larimer and Kenny Root Google I/O talk). In this case, the advertised identity must match one of the elements in the pinset.

You can read this series of react native articles that show you how to apply certificate pinning to protect the communication channel between your mobile app and the API server.

If you don't know yet certificcate pinning can also be bypassed by using tools like Frida or xPosed.

Frida

Inject your own scripts into black box processes. Hook any function, spy on crypto APIs or trace private application code, no source code needed. Edit, hit save, and instantly see the results. All without compilation steps or program restarts.

xPosed

Xposed is a framework for modules that can change the behavior of the system and apps without touching any APKs. That's great because it means that modules can work for different versions and even ROMs without any changes (as long as the original code was not changed too much). It's also easy to undo.

So now you may be wondering how can I protect from certificate pinning bypass?

Well is not easy, but is possible, by using a mobile app attestation solution.

Before we go further on it, I would like to clarify first a common misconception among developers, regarding WHO and WHAT is accessing the API server.

The Difference Between WHO and WHAT is Accessing the API Server

To better understand the differences between the WHO and the WHAT are accessing an API server, let’s use this picture:

The Intended Communication Channel represents the mobile app being used as you expected, by a legit user without any malicious intentions, using an untampered version of the mobile app, and communicating directly with the API server without being man in the middle attacked.

The actual channel may represent several different scenarios, like a legit user with malicious intentions that may be using a repackaged version of the mobile app, a hacker using the genuine version of the mobile app, while man in the middle attacking it, to understand how the communication between the mobile app and the API server is being done in order to be able to automate attacks against your API. Many other scenarios are possible, but we will not enumerate each one here.

I hope that by now you may already have a clue why the WHO and the WHAT are not the same, but if not it will become clear in a moment.

The WHO is the user of the mobile app that we can authenticate, authorize and identify in several ways, like using OpenID Connect or OAUTH2 flows.

OAUTH

Generally, OAuth provides to clients a "secure delegated access" to server resources on behalf of a resource owner. It specifies a process for resource owners to authorize third-party access to their server resources without sharing their credentials. Designed specifically to work with Hypertext Transfer Protocol (HTTP), OAuth essentially allows access tokens to be issued to third-party clients by an authorization server, with the approval of the resource owner. The third party then uses the access token to access the protected resources hosted by the resource server.

OpenID Connect

OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 protocol. It allows Clients to verify the identity of the End-User based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the End-User in an interoperable and REST-like manner.

While user authentication may let the API server know WHO is using the API, it cannot guarantee that the requests have originated from WHAT you expect, the original version of the mobile app.

Now we need a way to identify WHAT is calling the API server, and here things become more tricky than most developers may think. The WHAT is the thing making the request to the API server. Is it really a genuine instance of the mobile app, or is a bot, an automated script or an attacker manually poking around with the API server, using a tool like Postman?

For your surprise you may end up discovering that It can be one of the legit users using a repackaged version of the mobile app or an automated script that is trying to gamify and take advantage of the service provided by the application.

Well, to identify the WHAT, developers tend to resort to an API key that usually they hard-code in the code of their mobile app. Some developers go the extra mile and compute the key at run-time in the mobile app, thus it becomes a runtime secret as opposed to the former approach when a static secret is embedded in the code.

The above write-up was extracted from an article I wrote, entitled WHY DOES YOUR MOBILE APP NEED AN API KEY?, and that you can read in full here, that is the first article in a series of articles about API keys.

Mobile App Attestation

The use of a Mobile App Attestation solution will enable the API server to know WHAT is sending the requests, thus allowing to respond only to requests from a genuine mobile app while rejecting all other requests from unsafe sources.

The role of a Mobile App Attestation service is to guarantee at run-time that your mobile app was not tampered, is not running in a rooted device and is not being the target of a MitM attack. This is done by running a SDK in the background that will communicate with a service running in the cloud to attest the integrity of the mobile app and device is running on. The cloud service also verifies that the TLS certificate provided to the mobile app on the handshake with the API server is indeed the same in use by the original and genuine API server for the mobile app, not one from a MitM attack.

On successful attestation of the mobile app integrity a short time lived JWT token is issued and signed with a secret that only the API server and the Mobile App Attestation service in the cloud are aware. In the case of failure on the mobile app attestation the JWT token is signed with a secret that the API server does not know.

Now the App must sent with every API call the JWT token in the headers of the request. This will allow the API server to only serve requests when it can verify the signature and expiration time in the JWT token and refuse them when it fails the verification.

Once the secret used by the Mobile App Attestation service is not known by the mobile app, is not possible to reverse engineer it at run-time even when the App is tampered, running in a rooted device or communicating over a connection that is being the target of a Man in the Middle Attack.

So this solution works in a positive detection model without false positives, thus not blocking legit users while keeping the bad guys at bays.

What suggestions do you have to protect the world (react- native apps) from pesky hackers, when they're stealing keys and using them inappropriately?

I think you should relaly go with a mobile app attestation solution, that you can roll in your own if you have the expertise for it, or you can use a solution that already exists as a SAAS solution at Approov(I work here), that provides SDKs for several platforms, including iOS, Android, React Native and others. The integration will also need a small check in the API server code to verify the JWT token issued by the cloud service. This check is necessary for the API server to be able to decide what requests to serve and what ones to deny.

Summary

I want to be able to store keys in the app so that I can validate the user an allow them to access resources on the backend. However, I don't know what the best plan of action is to ensure user/business security.

Don't go down this route of storing keys in the mobile app, because as you already know, by your extensive research, they can be bypassed.

Instead use a mobile attestation solution in conjunction with OAUTH2 or OpenID connect, that you can bind with the mobile app attestation token. An example of this token binding can be found in this article for the check of the custom payload claim in the endpoint /forms.

Going the Extra Mile

OWASP Mobile Security Project - Top 10 risks

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. Through the project, our goal is to classify mobile security risks and provide developmental controls to reduce their impact or likelihood of exploitation.

这篇关于在 React Native 中存储密钥最安全的方式是什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆