2018年03月29日 17:39:36
pc端、安卓端微信数据库解密算法
安卓端微信数据库密码生成算法网上有文章介绍,这里不提了
pc端的密码生产算法在内存中加密了,有兴趣的朋友可以去看看密码如何生成的
拿到密码之后怎么解密sqlite数据库?有些朋友用sqlcipher死活解不开,其实是参数不对。
这里提供拿到密码之后的解密算法,兼容安卓上的、pc上的微信数据库。(免去到处找sqlcipher,又怕版本错误的问题)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include "stdafx.h"
#include <Windows.h>
#include <openssl/rand.h>
#include <openssl/evp.h>
#include <openssl/aes.h>
#include <openssl/hmac.h>
//#define ANDROID_WECHAT
#define SQLITE_FILE_HEADER "SQLite format 3" //length == 16
#define IV_SIZE 16
#define HMAC_SHA1_SIZE 20
#define KEY_SIZE 32
#ifndef ANDROID_WECHAT
#define DEFAULT_PAGESIZE 4096
#define DEFAULT_ITER 64000
#else
#define NO_USE_HMAC_SHA1
#define DEFAULT_PAGESIZE 1024
#define DEFAULT_ITER 4000
#endif
<br>
//安卓端这里密码是7位,pc端是经过算法得到的32位pass。
//下面附pc端拿密码的OD图
unsigned char pass[] = { 0x5C, 0xF8, 0x6A, 0x13, 0x61, 0xA1, 0x46, 0x14, 0x98, 0x6C, 0x2D, 0x6F, 0x5E, 0x6C, 0x16, 0x81, 0xB8,0xCF, 0x5D, 0x3F, 0xD2, 0xEB, 0x49, 0xCE, 0xAF, 0xFB, 0x88, 0xE3, 0xD8, 0x28, 0xC7, 0xBD };
int _tmain(int argc, _TCHAR* argv[])
{
FILE *fpdb = fopen("MicroMsg.db", "rb+");
if (!fpdb)
{
return 0;
}
fseek(fpdb, 0, SEEK_END);
long nFileSize = ftell(fpdb);
fseek(fpdb, 0, SEEK_SET);
unsigned char *pDbBuffer = new unsigned char[nFileSize];
fread(pDbBuffer, 1, nFileSize, fpdb);
fclose(fpdb);
unsigned char salt[16] = { 0 };
memcpy(salt, pDbBuffer, 16);
#ifndef NO_USE_HMAC_SHA1
unsigned char mac_salt[16] = { 0 };
memcpy(mac_salt, salt, 16);
for (int i = 0; i < sizeof(salt); i++)
{
mac_salt[i] ^= 0x3a;
}
#endif
int reserve = IV_SIZE;
#ifndef NO_USE_HMAC_SHA1
reserve += HMAC_SHA1_SIZE;
#endif
reserve = ((reserve % AES_BLOCK_SIZE) == 0) ? reserve : ((reserve / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE;
unsigned char key[KEY_SIZE] = { 0 };
unsigned char mac_key[KEY_SIZE] = { 0 };
OpenSSL_add_all_algorithms();
PKCS5_PBKDF2_HMAC_SHA1((const char *)pass, sizeof(pass), salt, sizeof(salt), DEFAULT_ITER, sizeof(key), key);
#ifndef NO_USE_HMAC_SHA1
PKCS5_PBKDF2_HMAC_SHA1((const char *)key, sizeof(key), mac_salt, sizeof(mac_salt), 2, sizeof(mac_key), mac_key);
#endif
unsigned char *pTemp = pDbBuffer;
unsigned char pDecryptPerPageBuffer[DEFAULT_PAGESIZE];
int nPage = 1;
int offset = 16;
while (pTemp < pDbBuffer + nFileSize)
{
printf("decrypt page:%d/%d \n", nPage, nFileSize / DEFAULT_PAGESIZE);
#ifndef NO_USE_HMAC_SHA1
//check hmac
unsigned char hash_mac[HMAC_SHA1_SIZE] = { 0 };
unsigned int hash_len = 0;
HMAC_CTX hctx;
HMAC_CTX_init(&hctx);
HMAC_Init_ex(&hctx, mac_key, sizeof(mac_key), EVP_sha1(), NULL);
HMAC_Update(&hctx, pTemp + offset, DEFAULT_PAGESIZE - reserve - offset + IV_SIZE);
HMAC_Update(&hctx, (const unsigned char *)&nPage, sizeof(nPage));
HMAC_Final(&hctx, hash_mac, &hash_len);
HMAC_CTX_cleanup(&hctx);
if (0 != memcmp(hash_mac, pTemp + DEFAULT_PAGESIZE - reserve + IV_SIZE, sizeof(hash_mac)))
{
//hash check err
return 0;
}
#endif
//
if (nPage == 1)
{
memcpy(pDecryptPerPageBuffer, SQLITE_FILE_HEADER, offset);
}
//aes decrypt
EVP_CIPHER_CTX* ectx = EVP_CIPHER_CTX_new();
EVP_CipherInit_ex(ectx, EVP_get_cipherbyname("aes-256-cbc"), NULL, NULL, NULL, 0);
EVP_CIPHER_CTX_set_padding(ectx, 0);
EVP_CipherInit_ex(ectx, NULL, NULL, key, pTemp + (DEFAULT_PAGESIZE - reserve), 0);
int nDecryptLen = 0;
int nTotal = 0;
EVP_CipherUpdate(ectx, pDecryptPerPageBuffer + offset, &nDecryptLen, pTemp + offset, DEFAULT_PAGESIZE - reserve - offset);
nTotal = nDecryptLen;
EVP_CipherFinal_ex(ectx, pDecryptPerPageBuffer + offset + nDecryptLen, &nDecryptLen);
nTotal += nDecryptLen;
EVP_CIPHER_CTX_free(ectx);
//assert(nTotal == DEFAULT_PAGESIZE - reserve - offset);
//no necessary ,just like sqlcipher
memcpy(pDecryptPerPageBuffer + DEFAULT_PAGESIZE - reserve, pTemp + DEFAULT_PAGESIZE - reserve, reserve);
FILE *fp = fopen("MicroMsg_Decrypt.db", "ab+");
{
fwrite(pDecryptPerPageBuffer, 1, DEFAULT_PAGESIZE, fp);
fclose(fp);
}
nPage++;
offset = 0;
pTemp += DEFAULT_PAGESIZE;
}<br>
return 0;
}
1