安全地将客户端证书和密钥(.pem)存储在Android中 [英] Store Client Certificate and key (.pem) in Android securely

查看:99
本文介绍了安全地将客户端证书和密钥(.pem)存储在Android中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个供内部使用的Android应用程序,用于将测试请求发送到我们的服务器.认证通过基本+客户证书进行.我现在正在做的是将证书和密钥文件存储在资产/证书中,通过输入获取密钥和基本身份验证的密码,然后保存在SharedPreferences中.这可能不安全.我最关心的是两个.pem文件.我读了很多关于将它们保存在Android Keystore中的信息,但是对此并不确定.是否可以安装"证书并随后删除pem文件?我在寻找解决方案的大部分时间中发现的是应用程序自身生成的证书存在问题.但是我只有两个.pem文件,需要使用它们来发送请求.

I am developing an Android App for internal use to send test requests to our server. The Authentification is via Basic + Client Certificate. What I am doing right now is storing cert and key file in assets/certs, getting the passphrase for the key and Basic Auth via input and then saved in SharedPreferences. This is probably not safe. I am mostly concerned about the two .pem-files. I read a lot about saving them in the Android Keystore, but not really sure about that. Is it possible to "install" the certificates and delete the pem files afterwards? What I found most of the time while searching for a solution were issues with self generated certificates from the app. But what I have are two .pem-files, that need to be used to send the request.

将证书存储在资产中后,我担心它会被反向工程.

With storing the certs in assets I am worried it can be reverse-engineered.

现在的示例代码:

SecurityContext context = SecurityContext.defaultContext;
ByteData cert = await rootBundle.load("assets/certs/xy.cert.pem");
context.useCertificateChainBytes(cert.buffer.asUint8List());
ByteData key = await rootBundle.load("assets/certs/xy.key.pem");
final storage = FlutterSecureStorage();
String passphrase = await storage.read(key: "passphrase");
String basic = await storage.read(key: "basic");
context.usePrivateKeyBytes(key.buffer.asUint8List(), password:passphrase);
HttpClient client = new HttpClient(context: context);
var uri = "https://url.com";
var method = 'POST';
var request = await client.openUrl(method,Uri.parse(uri));
request.headers.set('Content-Type', 'application/json; charset=utf-8');
request.headers.set("Authorization", basic);

工作正常,但我想确保它不能从其他应用程序中提取.

Works fine, but I want to make sure it can't be extracted from other apps.

可能应该提到它:我正在处理颤振,但这并不能使它变得更容易.

Probably should've mentioned it: I am working with flutter, which somehow does not make it easier.

推荐答案

Android共享的偏好设置或Android KEYSTORE?

我现在正在做的是将证书和密钥文件存储在资产/证书中,通过输入获取密钥和基本身份验证的密码,然后保存在SharedPreferences中.这可能不安全.

What I am doing right now is storing cert and key file in assets/certs, getting the passphrase for the key and Basic Auth via input and then saved in SharedPreferences. This is probably not safe.

是的,如果不对它们进行加密,那是绝对不安全的.

Yes is not safe at all if you don't encrypt them.

Android共享首选项

SharedPreferences对象指向一个包含键值对的文件,并提供简单的方法来读写它们.每个SharedPreferences文件都由框架管理,可以是私有的也可以是共享的.

A SharedPreferences object points to a file containing key-value pairs and provides simple methods to read and write them. Each SharedPreferences file is managed by the framework and can be private or shared.

使用Android密钥库加密的共享首选项

我主要关心两个.pem文件.我读过很多关于将它们保存在Android Keystore中的信息,但是对此并不太确定

I am mostly concerned about the two .pem-files. I read a lot about saving them in the Android Keystore, but not really sure about that

要加密共享首选项,我们需要使用 EncryptedSharedPreferences 并将加密密钥存储在您已经了解的Android密钥库中.

To encrypt the Shared preferences we need to use the class EncryptedSharedPreferences and store the encryption key in the Android Keystore as you already have read about.

Android硬件支持的密钥库

片上系统(SoC)中受信任的执行环境的可用性为Android设备提供了向Android OS,平台服务甚至第三方应用程序提供硬件支持的强大安全服务的机会.

The availability of a trusted execution environment in a system on a chip (SoC) offers an opportunity for Android devices to provide hardware-backed, strong security services to the Android OS, to platform services, and even to third-party apps.

为了帮助您更安全地处理数据,Android为您提供了安全库:

To help you working with data more securely Android provides you the Security Library:

安全库提供了与静态数据读取和写入以及密钥创建和验证有关的安全最佳实践的实现.

The Security library provides an implementation of the security best practices related to reading and writing data at rest, as well as key creation and verification.

Android文档中的示例:

他们只提供 Kotlin Java 的示例,没有Flutter,因此我将Kotlin的示例复制粘贴到这里.

Examples from Android docs:

They only provide examples in Kotlin or Java, no Flutter, therefore I copy paste here the Kotlin ones.

:

// Although you can define your own key generation parameter specification, it's
// recommended that you use the value specified here.
val keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC
val masterKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec)

// Creates a file with this name, or replaces an existing file
// that has the same name. Note that the file name cannot contain
// path separators.
val fileToWrite = "my_sensitive_data.txt"
val encryptedFile = EncryptedFile.Builder(
    File(DIRECTORY, fileToWrite),
    context,
    masterKeyAlias,
    EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
).build()

val fileContent = "MY SUPER-SECRET INFORMATION"
        .toByteArray(StandardCharsets.UTF_8))
encryptedFile.openFileOutput().apply {
    write(fileContent)
    flush()
    close()
}

阅读

// Although you can define your own key generation parameter specification, it's
// recommended that you use the value specified here.
val keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC
val masterKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec)

val context = applicationContext
val fileToRead = "my_sensitive_data.txt"
val encryptedFile = EncryptedFile.Builder(
    File(DIRECTORY, fileToRead),
    context,
    masterKeyAlias,
    EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
).build()

val inputStream = encryptedFile.openFileInput()
val byteArrayOutputStream = ByteArrayOutputStream()
var nextByte: Int = inputStream.read()
while (nextByte != -1) {
    byteArrayOutputStream.write(nextByte)
    nextByte = inputStream.read()
}

val plaintext: ByteArray = byteArrayOutputStream.toByteArray()

逆向工程

将证书存储在资产中后,我担心它会被反向工程.

With storing the certs in assets I am worried it can be reverse-engineered.

无论您如何存储它们,都可以进行逆向工程,即使使用我提到的上述方法.

No matter how you store them, they can be reverse engineered, even with the above method I mentioned.

在这种情况下,攻击者将诉诸于使用检测框架,并在运行时将其挂钩到检索和解密pem证书的代码中,然后将其提取到其命令和控制服务器,然后他可以从该服务器对您的攻击自动进行攻击后端.

An attacker will resort in this case to use an instrumentation framework and hook at runtime into the code that retrieves and decrypts the pem certificates, and then extracting them to his command and control server, from where he can then automate attacks against your backend.

Instrumentation框架的示例是 Frida :

An example of an Instrumentation framework is Frida:

将您自己的脚本注入黑匣子进程.挂钩任何功能,监视加密API或跟踪私有应用程序代码,不需要任何源代码.编辑,点击保存,立即查看结果.全部没有编译步骤或程序重新启动.

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.

请记住,任何您想在移动应用程序中保密的内容实际上都是公开的,因为它只需要攻击者使用使此任务容易的大量开源工具即可.

Remember that anything you want to keep private in a mobile app is in fact public, because it just needs an attacker to use the vast array of open source tools that make this tasks easy.

工作正常,但我想确保它不能从其他应用程序中提取.

Works fine, but I want to make sure it can't be extracted from other apps.

由于您已经意识到自己不可能从移动应用程序中提取pem文件,因此只能使其变得更加困难.

As you already realized you cannot make impossible to extract the pem files from your mobile app, you can make it only more difficult.

针对您的问题的一种可能的解决方案是使您的后端能够知道自己何时可以高度信任地信任确实来自您的移动应用程序的请求,从而允许其拒绝正在从您的移动应用程序提取的pem文件的请求.从其他地方使用.

A possible solution for your problem is to empower your backend to know when he can trust with high confidence that a request is coming indeed from your mobile app, thus allowing it to refuse requests where pem files extracted from your mobile app are being used from elsewhere.

我建议您阅读

I recommend you to read the answer I gave to the question How to secure an API REST for mobile app?.

我要求您首先了解什么之间在访问您的后端之间的区别,因为这在开发人员中是一个普遍的误解,导致他们相信用户身份验证足以证明正在做什么向后端发出请求,而实际上只是证明是请求中的用户.话虽如此,我仍然建议使用适合移动应用程序用例和用户群的强大用户身份验证解决方案.

I ask you to first understand the difference between who vs what is accessing your backend, because its a common misconception among developers, that led them to believe that user authentication is enough to attest what is doing the request to the backend, when in fact it just attests who is the user in the request. This being said I still recommend to use strong user authentication solutions that are adequate to the mobile app use case and user base of it.

在您清楚地知道了区别之后,您可以继续阅读其余的答案,并查看保护API服务器部分中的建议是否足够,或者您需要使用移动版应用程序证明的概念,如可能的更好解决方案部分所述.

After that difference is clear in your mind you can proceed to read the rest of the answer and see if the recommendations in the section Securing the API server are enough or you need to go for the Mobile App Attestation concept as described in the section A Possible Better Solution.

在回答安全问题时,我总是喜欢引用OWASP基金会的宝贵工作:)

In any response to a security question I always like to reference the invaluable work from the OWASP foundation :)

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

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

OWASP-移动安全测试指南:

移动安全测试指南(MSTG)是用于移动应用安全开发,测试和逆向工程的综合手册.

The Mobile Security Testing Guide (MSTG) is a comprehensive manual for mobile app security development, testing and reverse engineering.

对于APIS

OWASP API安全性排名前10位

OWASP API安全项目旨在通过强调不安全API中的潜在风险并说明如何减轻这些风险来为软件开发人员和安全评估人员提供价值.为了实现此目标,OWASP API安全项目将创建并维护十大API安全风险"文档,以及用于创建或评估API的最佳实践的文档门户.

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. 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.

这篇关于安全地将客户端证书和密钥(.pem)存储在Android中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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