android 字符串 防止内存嗅探方法
最近想做一个android端文档加密app。个人希望能做出一个连写这个app的程序员都无法查看私密内容程序。
加密本身使用的是AES,是可靠的。
用户需要输入密码才能查看文档信息,app切换到后台一段时间销毁密码。
如果是c语言
char password="123456789"
销毁密码时候
for(int i=0;i<10;i++)
password=0x00
我相信不法者(即使我自己)都无法再从内存中找到曾经输入过的密码。
可是android一般用的java
程序中可能有类似
String password=”用户输入密码“
虽然可以用定时器以及定时服务在程序切换到后台一段时间后销毁密码
password=null
但是内存中依然可以找到password旧值(java机制,似乎字符串赋新值实际是为变量分配新的空间存放新字符串,而旧的字符串可能依然存在。使用一些内存查看程序可以看app内存值)
程序不大,代码混淆对程序开发者阻碍有限。
密码可以用某固定key进行二次加密,但是加密前字符串也可能驻留内存,并且开发者也有能力根据加密后字符串推算出原密码。
android很多人除了重启都是不退出app的,所以内存中旧密码可以保存很久
那么android java下有什么办法销毁旧字符串值。或者有没有其他可行解决办法
自己问题自己解
这是java机制问题本身无解
虽然java中有byte[]存在可以很容易清除数据,但是界面上文本框,string类型参数传递等过程不可避免在内存中产生临时变量
我能做的是避免密钥与特殊字符串一起出现。
比如intent.putExtra("password",password)语句会使得内存中“password”与真实密钥一同出现
使用intent.putExtra("p",password) 替换
如果有更好办法欢迎提 有什么意义么。我是没看出来。如果可以搜索内存。说明有root。都有root了,直接hook参数不久知道密码了。而且如果文档本身就是加密的,在一台没有root的手机上,输入了密码在内存也无所谓啊,所以我看不出来有什么意思。不过如果是一些游戏app加密数值的话,貌似是对某个数据加密储存,ui显示的是另一个变量,而实际储存值得变量是加密过的,去运算都是用这个加密的值去验证,不知道这个对你有没有用 lemniscate 发表于 2019-7-6 22:10
有什么意义么。我是没看出来。如果可以搜索内存。说明有root。都有root了,直接hook参数不久知道密码了。而 ...
我确实忘记了最重要的权限问题,现在补充下
假设场景下有用户和开发者两个角色,只有用户知道密码,而开发者有源码,为了向用户证明程序没有后门,源码已经开源。现在只要能使得开发者在不知道密码情况下也无法知道文档内容,那么程序就是安全的。
假设安卓系统中有个读写文件的api,读写系统文件时候需要管理员权限。如果利用这个api改了系统权限配置相关代码,允许用户将特定程序运行于ring0级别,就可以说利用文件api漏洞root了手机,要使新权限管理生效会要求重启(对我app无害)
另外android端有八门神器,gg修改器不用root查看修改内存的app,但是这类app似乎要求成为目标app的父进程(这会导致重新打开app,已经是新的内存空间了)
然后我使用android studio 附加调试app(既然是做安全的,就不太该依赖其他程序安全性,所以假设开机密码已经被破解了),发现局部变量一览无余。windows下windbg,linux gdb都能查看寄存器,内存值,那么android的应该也有类似指令((adb shell dumpsys meminfo $package_name or $pid //使用程序的包名或者进程id)不知这个可行不)
单纯要看内存值得话只需要管理员权限调用内存相关api就行了,不需要root。
至于你说的内存中只存二次加密后密钥方法,你觉得开发者用某加密算法加密后能骗过开发者本人吗?
最最重要的,但凡有用户输入密码解密过程,解密函数入口AES_decrypt(data,password)就会暴露真正密钥。c语言在解密过程结束后用全0覆盖堆栈覆盖局部变量就能高枕无忧。java好像没办法稳定消除String类型password曾经被赋予值。这也是本次问题核心
页:
[1]