移动应用安全开发指南(Android)--数据存储
1、数据存储
|
概述 |
移动应用经常需要在某些场景下(比如用户登录)处理和用户或业务相关的敏感数据,有时候为满足某些业务需求,需要把这些敏感数据存储在本地,如果不对这些数据进行适当处理,就有可能存在敏感信息泄漏的风险。 |
|
|
安全准则 |
A. 敏感数据总是优先考虑存储在内部空间。 B. 敏感数据无论是存储在内部还是外部空间均应经过加密后再存储,应避免直接明文存储。 C. 避免将敏感数据存储在全局可访问的缓存里(如log、剪切板等)。 D. 敏感数据避免硬编码在代码里面,常见的有用户账户口令和加密密钥等。 |
|
|
详细描述 |
A. 可以使用JDK提供的javax.crypto包进行加/解密,注意加密算法的选择以及密钥复杂度策略(参考第6条以及附录1)。 B. 使用System.out.print系列以及android.util.Log类的方法(比如Log.d())会将日志存储在系统缓冲区,任意应用都可以通过logcat指令查看缓存里面的敏感信息(比如密码和sessionID等),因此Release版本应移除这些主要用于debug的方法。 |
|
|
备注 |
A. 常见的敏感数据有用户口令、用户个人信息和sessionID等等,但也有一些是和业务强相关的,当不太容易判断时,可以和安全工程师一起确认。 B. Android使用沙箱技术对不同应用之间的内部存储空间进行了隔离,但考虑到应用自身的漏洞(比如SQL注入)和ROOT的场景,对内部存储数据进行加密还是非常必要的。 |
|
提示:如果IE显示不正常,请使用chrome浏览器
附录1:
1、安全的加/解密方案:
1.1、AES128对称加密方案:
public class AES128Enc {
public static String encrypt(byte[] rawKey, String cleartext) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(rawKey, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(cleartext.getBytes());
return toHex(encrypted);
}
public static String decrypt(byte[] rawKey, String encrypted) throws Exception {
byte[] enc = toByte(encrypted);
SecretKeySpec skeySpec = new SecretKeySpec(rawKey, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(enc);
return new String(decrypted);
}
/* 产生随机的128bit AES密钥 */
public static byte[] getRawKey(byte[] seed) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed);
kgen.init(128, sr);
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
return raw;
}
public static byte[] toByte(String hexString) {
int len = hexString.length()/2;
byte[] result = new byte[len];
for (int i = 0; i < len; i++)
result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue();
return result;
}
public static String toHex(byte[] buf) {
if (buf == null)
return "";
StringBuffer result = new StringBuffer(2*buf.length);
for (int i = 0; i < buf.length; i++) {
appendHex(result, buf[i]);
}
return result.toString();
}
private final static String HEX = "0123456789ABCDEF";
private static void appendHex(StringBuffer sb, byte b) {
sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f));
}
}
1.2、SHA256哈希算法:
public class Sha256Hash {
private static byte [] getHash(String strForHash) {
MessageDigest digest = null ;
try {
digest = MessageDigest. getInstance( "SHA-256");
} catch (NoSuchAlgorithmException e1) {
e1.printStackTrace();
}
digest.reset();
return digest.digest(strForHash.getBytes());
}
public static String bin2hex(String strForHash) {
byte [] data = getHash(strForHash);
return String.format( "%0" + (data.length * 2) + "X", new BigInteger(1, data));
}
}
移动应用安全开发指南(Android)--数据存储的更多相关文章
- Android开发学习——android数据存储
Android的存储 Android中的数据存储方式及其存储位置 SharedPrefrence存储 1). 位置 /data/data/packageName/shared_pr ...
- 【Android 应用开发】Android 数据存储 之 SQLite数据库详解
. 作者 :万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/19028665 . SQLiteDataBase示例程序下 ...
- 移动应用安全开发指南(Android)--数据验证
概述 移动应用往往通过数据的发送.接收和处理来完成一系列功能,通常情况下,处理的数据绝大部分都来源于外部(比如网络.内部或外部存储和用户输入等),对这些数据处理不当会导致各种各样的漏洞和风险,比代码执 ...
- 【Android开发日记】之入门篇(七)——Android数据存储(上)
在讲解Android的数据源组件——ContentProvider之前我觉得很有必要先弄清楚Android的数据结构. 数据和程序是应用构成的两个核心要素,数据存储永远是应用开发中最重要的主题之一,也 ...
- 【Android开发日记】之入门篇(八)——Android数据存储(下)
废话不多说了,紧接着来讲数据库的操作吧.Come On! 提到数据存储问题,数据库是不得不提的.数据库是用来存储关系型数据的不二利器.Android为开发者提供了强大的数据库支持,可以用来轻松地构造基 ...
- Android数据存储之SQLCipher数据库加密
前言: 最近研究了Android Sqlite数据库(文章地址:Android数据存储之Sqlite的介绍及使用)以及ContentProvider程序间数据共享(Android探索之ContentP ...
- Android数据存储之SQLite数据库
Android数据存储 之SQLite数据库简介 SQLite的相关知识,并结合Java实现对SQLite数据库的操作. SQLite是D.Richard Hipp用C语言编写的开源嵌入式数据库引擎. ...
- Android数据存储之GreenDao 3.0 详解
前言: 今天一大早收到GreenDao 3.0 正式发布的消息,自从2014年接触GreenDao至今,项目中一直使用GreenDao框架处理数据库操作,本人使用数据库路线 Sqlite----> ...
- Android数据存储方式--SharedPreferences
Android数据存储方式有如下四种:SharedPreferences.存储到文件.SQLite数据库.内容提供者(Content provider).存储到网络服务器. 本文主要介绍一下Share ...
- Android数据存储-通过SharedPreferences实现记住密码的操作
在Android中登陆中,为了实现用户的方便,往往需要根据用户的需要进行记住密码的操作,所以,在Android数据存储中SharedPreferences恰恰可以实现这一点 下面,小编将带领大家通过S ...
随机推荐
- Linux进程调度与源码分析(二)——进程生命周期与task_struct进程结构体
1.进程生命周期 Linux操作系统属于多任务操作系统,系统中的每个进程能够分时复用CPU时间片,通过有效的进程调度策略实现多任务并行执行.而进程在被CPU调度运行,等待CPU资源分配以及等待外部事件 ...
- WAMP Apache 2.5 配置虚拟主机
1.在 Apache 的安装目录下 conf/httpd.conf 文件中搜索 hosts,去掉 Include 前面的 “#” 号后,即可启用虚拟主机. # Virtual hosts #Inclu ...
- 学习 Linux,101: 自定义或编写简单脚本【转】
转自:http://www.ibm.com/developerworks/cn/linux/l-lpic1-105-2/index.html 学习如何使用标准的 shell 语法.循环和控制结构,以及 ...
- Android内存溢出解决方案总结
我的视频会议中有三个内存泄露的崆点: 1) BNLiveControlView mView = this; 未释放 (自定义view中自己引用自己造成) 2) 在自定义View中区注册了系统的网络变化 ...
- BestCoder Round #86 二,三题题解(尺取法)
第一题太水,跳过了. NanoApe Loves Sequence题目描述:退役狗 NanoApe 滚回去学文化课啦! 在数学课上,NanoApe 心痒痒又玩起了数列.他在纸上随便写了一个长度为 nn ...
- 【hdoj_2079】选课时间(母函数)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=2079 此题采用母函数的知识求解,套用母函数模板即可: http://blog.csdn.net/ten_s ...
- 【JBPM4】判断节点decision 方法3 handler
JPDL <?xml version="1.0" encoding="UTF-8"?> <process key="decision ...
- nginx 开启 gzip
gzip on; gzip_min_length 1k; gzip_buffers 4 16k; gzip_comp_level 2; gzip_types text/plain applicatio ...
- 前端读者 | 前端用户体验-UI动效设计
本文来自互联网 @羯瑞 整理 UI动效现如今在 APP 和网页中几乎已经成为了基本的组成部分,经过仔细打磨的 UI动效对于整个界面的提升是显著的. 动效呈现出状态切换的过程,展现了元素之间的逻辑关系, ...
- 前端读者 | 前端面试基础手册(HTML+CSS)
本文来自@羯瑞:希望前端面试基础手册能帮助要找工作的前端小伙伴~~ HTML 前端需要注意哪些SEO? 合理的title.description.keywords:搜索对着三项的权重逐个减小,titl ...