Android应用安全开发之浅谈密钥硬编码

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 在阿里聚安全的漏洞扫描器中和人工APP安全审计中,经常发现有开发者将密钥硬编码在Java代码、文件中,这样做会引起很大风险。


Android应用安全开发之浅谈密钥硬编码


作者:伊樵、呆狐@阿里聚安全


1 简介

在阿里聚安全的漏洞扫描器中和人工APP安全审计中,经常发现有开发者将密钥硬编码在Java代码、文件中,这样做会引起很大风险。信息安全的基础在于密码学,而常用的密码学算法都是公开的,加密内容的保密依靠的是密钥的保密,密钥如果泄露,对于对称密码算法,根据用到的密钥算法和加密后的密文,很容易得到加密前的明文对于非对称密码算法或者签名算法,根据密钥和要加密的明文,很容易获得计算出签名值,从而伪造签名。


2 风险案例

密钥硬编码在代码中,而根据密钥的用途不同,这导致了不同的安全风险,有的导致加密数据被破解,数据不再保密,有的导致和服务器通信的加签被破解,引发各种血案,以下借用乌云上已公布的几个APP漏洞来讲讲

2.1 某互联网金融APP加密算法被破解导致敏感信息泄露

某P2P应用客户端,用来加密数据的DES算法的密钥硬编码在Java代码中,而DES算法是对称密码算法,既加密密钥和解密密钥相同。 
反编译APP,发现DES算法:

发现DES算法的密钥,硬编码为“yrdAppKe”,用来加密手势密码:

 

将手势密码用DES加密后存放在本地LocusPassWordView.xml文件中:

知道了密文和加密算法以及密钥,通过解密操作,可以从文件中恢复出原始的手势密码。或者使用新的生成新的手势密码

而与服务器通信时接口中的Jason字段也用了DES算法和密钥硬编码为“yRdappKY”:



和服务器通信采用http传输,没有使用https来加密通信,如果采用中间人攻击或者路由器镜像,获得流量数据,可以破解出用户的通信内容。

2.2 某租车APP加密算法被破解导致一系列风险

某租车APP与服务器通信的接口采用http传输数据,并且有对传输的部分参数进行了加密,加密算法采用AES,但是密钥硬编码在java代码中为“shenzhoucar123123”,可被逆向分析出来,导致伪造请求,结合服务器端的漏洞,引起越权访问的风险,如越权查看其它用户的订单等。 
和服务器通信时的数据为:

q字段是加密后的内容。逆向APP,从登录Activity入手:


分析登录流程:v1是用户名,v2是密码,v3是PushId,在用户名和密码不为空并且长度不小于11情况下,执行LoginOperate相关操作,追踪LoginOperate的实现,发现继承自BaseOperate,继续追踪BaseOperate的实现:

在BaseOperate的initUrl()方法中,找到了APP是怎么生成请求数据的:

继续追踪上图中的initJsonUrl()方法,发现其调用了AES加密:

继续追踪aes.onEncrypt()函数:

在onEncrypt()函数中调用了encrypt()函数用来加密数据,追踪encrypt()函数的实现,发现其使用AES算法,并且密钥硬编码在java代码中为“shenzhoucar123123”

到现在请求中的数据加密如何实现的就清晰了,另外由于服务器权限控制不严,就可以构造订单id的请求,达到越权访问到其他用户的订单。 
构造{“id”:”11468061”}的请求:

其中uid设置为你自己的uid即可,可以成功看到其他人的订单:

攻击者完全可以做到使用其他脚本重新实现相同的加密功能并拼接出各个接口请求,批量的刷取订单信息和用户其他信息。

2.3 某酒店APP加签算法被破解导致一系列风险

某酒店APP和服务器通信时接口采用http通信,数据进行了加密,并且对传输参数进行签名,在服务器端校验签名,以检查传输的数据是否被篡改,但是加签算法和密钥被逆向分析,可导致加签机制失效,攻击者可任意伪造请求包,若结合服务器端的权限控制有漏洞,则可引发越权风险等。

APP和服务器通信的原始包如下图,可以看到有加签字段sign:

逆向APP定位到加密算法的逻辑代码,com.htinns.biz.HttpUtils.class,其实现逻辑为:

原始数据是unSignData,使用RC4算法加密,密钥为KEY变量所代表的值,加密后的数据为signData,传输的数据时的data字段为signData。 
加签字段signd的生成方法是用unsignData拼接时间戳time和resultkey,然后做md5,再进行base64编码。时间戳保证了每次请求包都不一样。 
sendSign()算法是用c或c++写的,放入了so库,其他重要算法都是用java写的。 
可以使用IDA逆向分析so库,找到sendSign()方法


而乌云漏洞提交者采用的是分析sign和getSign(sign)的数据,做一个算法破解字典。其实还有种方法直接调用此so库,来生成字典。

签名破解以后,就可以构造发送给服务器的数据包进行其他方面的安全测试,比如越权、重置密码等。


3 阿里聚安全开发建议

通过以上案例,并总结下自己平时发现密钥硬编码的主要形式有: 

1、密钥直接明文存在sharedprefs文件中,这是最不安全的。 
2、密钥直接硬编码在Java代码中,这很不安全,dex文件很容易被逆向成java代码。 
3、将密钥分成不同的几段,有的存储在文件中、有的存储在代码中,最后将他们拼接起来,可以将整个操作写的很复杂,这因为还是在java层,逆向者只要花点时间,也很容易被逆向。 
4、用ndk开发,将密钥放在so文件,加密解密操作都在so文件里,这从一定程度上提高了的安全性,挡住了一些逆向者,但是有经验的逆向者还是会使用IDA破解的。 
5、在so文件中不存储密钥,so文件中对密钥进行加解密操作,将密钥加密后的密钥命名为其他普通文件,存放在assets目录下或者其他目录下,接着在so文件里面添加无关代码(花指令),虽然可以增加静态分析难度,但是可以使用动态调式的方法,追踪加密解密函数,也可以查找到密钥内容。

保证密钥的安全确是件难事,涉及到密钥分发,存储,失效回收,APP防反编译和防调试,还有风险评估。可以说在设备上安全存储密钥这个基本无解,只能选择增大攻击者的逆向成本,让攻击者知难而退。而要是普通开发者的话,做妥善保护密钥这些事情这需要耗费很大的心血。

产品设计者或者开发者要明白自己的密钥是做什么用的,重要程度怎么样,密钥被逆向出来会造成什么风险,通过评估APP应用的重要程度来选择相应的技术方案。

所以建议不妨试试阿里聚安全的安全加固和安全组件,其中安全组件中的安全加密功能提供了开发者密钥的安全管理与加密算法实现,保证密钥的安全性,实现安全的加解密操作;安全签名功能实现客户端请求的签名处理,保证客户端与服务端通信请求不被伪造。安全加固提升安全等级,防止应用被逆向破解。这样同时从应用层、运行层、native层提供多层次全方位立体防护,另外还有安全沙箱、白盒加密、底层加固共同保证客户端数据安全。攻防是不断变化演进的,阿里聚安全提供的服务能实时更新客户端模块,通过阿里聚安全的漏洞扫描来检测应用是否具有密钥硬编码风险,保证在攻防对抗中永远处于上风。

专业的事情交给专业的人来做,自己的主要精力用来做功能开发或者业务逻辑,快速打造能赢得市场的可靠产品才是王道。


参考

[1] http://www.wooyun.org/bugs/wooyun-2010-0187287 
[2] http://www.wooyun.org/bugs/wooyun-2010-0105766 
[3] http://www.wooyun.org/bugs/wooyun-2015-0162907 
[4] http://jaq.alibaba.com/safety?spm=a313e.7837752.1000001.1.zwCPfa 

[5] https://www.zhihu.com/question/35136485/answer/84491440




作者:伊樵、呆狐@阿里聚安全,更多安全技术文章,请访问阿里聚安全博客



阿里聚安全由阿里巴巴移动安全部出品,面向企业和开发者提供企业安全解决方案,全面覆盖移动安全、数据风控、内容安全、实人认证等维度,并在业界率先提出“以业务为中心的安全”,赋能生态,与行业共享阿里巴巴集团多年沉淀的专业安全能力。


相关文章
|
1月前
|
缓存 搜索推荐 Android开发
安卓开发中的自定义控件实践
【10月更文挑战第4天】在安卓开发的海洋中,自定义控件是那片璀璨的星辰。它不仅让应用界面设计变得丰富多彩,还提升了用户体验。本文将带你探索自定义控件的核心概念、实现过程以及优化技巧,让你的应用在众多竞争者中脱颖而出。
|
1月前
|
Java Android开发 Swift
安卓与iOS开发对比:平台选择对项目成功的影响
【10月更文挑战第4天】在移动应用开发的世界中,选择合适的平台是至关重要的。本文将深入探讨安卓和iOS两大主流平台的开发环境、用户基础、市场份额和开发成本等方面的差异,并分析这些差异如何影响项目的最终成果。通过比较这两个平台的优势与挑战,开发者可以更好地决定哪个平台更适合他们的项目需求。
100 1
|
8天前
|
编解码 Java Android开发
通义灵码:在安卓开发中提升工作效率的真实应用案例
本文介绍了通义灵码在安卓开发中的应用。作为一名97年的聋人开发者,我在2024年Google Gemma竞赛中获得了冠军,拿下了很多项目竞赛奖励,通义灵码成为我的得力助手。文章详细展示了如何安装通义灵码插件,并通过多个实例说明其在适配国际语言、多种分辨率、业务逻辑开发和编程语言转换等方面的应用,显著提高了开发效率和准确性。
|
7天前
|
Android开发 开发者 UED
安卓开发中自定义View的实现与性能优化
【10月更文挑战第28天】在安卓开发领域,自定义View是提升应用界面独特性和用户体验的重要手段。本文将深入探讨如何高效地创建和管理自定义View,以及如何通过代码和性能调优来确保流畅的交互体验。我们将一起学习自定义View的生命周期、绘图基础和事件处理,进而探索内存和布局优化技巧,最终实现既美观又高效的安卓界面。
19 5
|
5天前
|
JSON Java Android开发
探索安卓开发之旅:打造你的第一个天气应用
【10月更文挑战第30天】在这个数字时代,掌握移动应用开发技能无疑是进入IT行业的敲门砖。本文将引导你开启安卓开发的奇妙之旅,通过构建一个简易的天气应用来实践你的编程技能。无论你是初学者还是有一定经验的开发者,这篇文章都将成为你宝贵的学习资源。我们将一步步地深入到安卓开发的世界中,从搭建开发环境到实现核心功能,每个环节都充满了发现和创造的乐趣。让我们开始吧,一起在代码的海洋中航行!
|
6天前
|
缓存 数据库 Android开发
安卓开发中的性能优化技巧
【10月更文挑战第29天】在移动应用的海洋中,性能是船只能否破浪前行的关键。本文将深入探讨安卓开发中的性能优化策略,从代码层面到系统层面,揭示如何让应用运行得更快、更流畅。我们将以实际案例和最佳实践为灯塔,引领开发者避开性能瓶颈的暗礁。
22 3
|
9天前
|
存储 IDE 开发工具
探索Android开发之旅:从新手到专家
【10月更文挑战第26天】在这篇文章中,我们将一起踏上一段激动人心的旅程,探索如何在Android平台上从零开始,最终成为一名熟练的开发者。通过简单易懂的语言和实际代码示例,本文将引导你了解Android开发的基础知识、关键概念以及如何实现一个基本的应用程序。无论你是编程新手还是希望扩展你的技术栈,这篇文章都将为你提供价值和启发。让我们开始吧!
|
1月前
|
Web App开发 安全 程序员
FFmpeg开发笔记(五十五)寒冬里的安卓程序员可进阶修炼的几种姿势
多年的互联网寒冬在今年尤为凛冽,坚守安卓开发愈发不易。面对是否转行或学习新技术的迷茫,安卓程序员可从三个方向进阶:1)钻研谷歌新技术,如Kotlin、Flutter、Jetpack等;2)拓展新功能应用,掌握Socket、OpenGL、WebRTC等专业领域技能;3)结合其他行业,如汽车、游戏、安全等,拓宽职业道路。这三个方向各有学习难度和保饭碗指数,助你在安卓开发领域持续成长。
60 1
FFmpeg开发笔记(五十五)寒冬里的安卓程序员可进阶修炼的几种姿势
|
15天前
|
Java API Android开发
安卓应用程序开发的新手指南:从零开始构建你的第一个应用
【10月更文挑战第20天】在这个数字技术不断进步的时代,掌握移动应用开发技能无疑打开了一扇通往创新世界的大门。对于初学者来说,了解并学习如何从无到有构建一个安卓应用是至关重要的第一步。本文将为你提供一份详尽的入门指南,帮助你理解安卓开发的基础知识,并通过实际示例引导你完成第一个简单的应用项目。无论你是编程新手还是希望扩展你的技能集,这份指南都将是你宝贵的资源。
43 5
|
13天前
|
设计模式 IDE Java
探索安卓开发:从新手到专家的旅程
【10月更文挑战第22天】 在数字时代的浪潮中,移动应用开发如同一座金矿,吸引着无数探险者。本文将作为你的指南针,指引你进入安卓开发的广阔天地。我们将一起揭开安卓平台的神秘面纱,从搭建开发环境到掌握核心概念,再到深入理解安卓架构。无论你是初涉编程的新手,还是渴望进阶的开发者,这段旅程都将为你带来宝贵的知识和经验的财富。让我们开始吧!