作为项目的一部分,我们正尝试在Google Chrome中解密已保存的密码。经过一番挖掘,我们了解到Chrome使用CryptProtectData功能对密码进行加密,该功能允许您使用登录用户凭据加密数据,即加密数据只能由同一用户在同一台机器上解密(如果提供适当的参数,也可以在其他用户处解密)。
无论如何,我之前已经编写了一个Python脚本来做到这一点,它完全正常。
class StringGeneratorWebService(object):
exposed = True
@cherrypy.tools.accept(media='text/plain')
def GET(self):
return cherrypy.session['mystring']
def POST(self, length=8):
some_string = ''.join(random.sample(string.hexdigits, int(length)))
cherrypy.session['mystring'] = some_string
return some_string
def PUT(self, another_string):
cherrypy.session['mystring'] = another_string
def DELETE(self):
cherrypy.session.pop('mystring', None)
但由于项目要求,我必须用C语言编写代码。 所以我写了下面的代码:
from os import getenv, unlink
from shutil import copy
import sqlite3
import win32crypt
dbpath = "C:\Users\\"+ getenv('username') +"\AppData\Local\Google\Chrome\User Data\Default\\"
copy(dbpath + "Login Data", dbpath + "Login Data.db")
conn = sqlite3.connect(dbpath + "Login Data.db")
cursor = conn.cursor()
cursor.execute('SELECT action_url, username_value, password_value FROM logins')
for result in cursor.fetchall():
password = win32crypt.CryptUnprotectData(result[2], None, None, None, 0)[1]
print result[0] + " - " + result[1] + ":" + password
conn.close()
unlink(dbpath + "Login Data.db")
它正确编译没有任何错误,但解密数据不正确。
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <Wincrypt.h>
#include "sqlite3.h"
static int callback(void *data, int argc, char **argv, char **azColName){
int i;
fprintf(stderr, "%s: \n", (const char*)data);
for(i=0; i<argc; i++){
if (i == 2 ){
DATA_BLOB DataIn;
DATA_BLOB DataOut;
BYTE *pbDataInput = (BYTE *) argv[i];
DWORD cbDataInput = strlen((char *) pbDataInput) + 1;
DataIn.pbData = pbDataInput;
DataIn.cbData = cbDataInput;
if (CryptUnprotectData (&DataIn, NULL, NULL, NULL, NULL, 0, &DataOut))
printf("%s\n", DataOut.pbData);
else
printf("Error number %x.\n", GetLastError());
}
// printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}
int main(int argc, char* argv[])
{
sqlite3 *db;
char *zErrMsg = 0;
int rc;
char *sql;
const char* data = "Callback function called";
/* Open database */
rc = sqlite3_open("Login Data.db", &db);
if( rc ){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
return(0);
}else{
fprintf(stderr, "Opened database successfully\n");
}
/* Create SQL statement */
sql = "SELECT action_url, username_value, password_value from logins";
/* Execute SQL statement, */
rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
fprintf(stdout, "Operation done successfully\n");
}
sqlite3_close(db);
return 0;
}
根据System Error Codes (0-499), 0x57用于ERROR_INVALID_PARAMETER(参数不正确)
我错过了什么?
答案 0 :(得分:0)
这对我来说很好,因为你在2hex.txt中有你的加密数据(只是从数据库浏览器保存它)。你的问题实际上是在strlen()函数中,因为它首先符合&#34; 0&#34;以字节顺序停止。只是避免它。
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <Wincrypt.h>
int main(){
FILE *fp;
DATA_BLOB DataIn;
DATA_BLOB DataOut;
char result[1000]="";
unsigned char buf[1000]="";
int tmpbuf;
int i=0;
fp=fopen("3hex.txt","rb");
printf ("Crypted data:\n");
for(i=0;(tmpbuf=getc(fp))!=EOF;i++)
{
buf[i]=tmpbuf;
if (i%16==0) printf("\n");
printf("%02X ",buf[i]);
}
DataIn.pbData=buf;
DataIn.cbData=i+1;
if (CryptUnprotectData (&DataIn, NULL, NULL, NULL, NULL, 0, &DataOut))
{
for (i=0;i<DataOut.cbData;i++)
{
result[i]=DataOut.pbData[i];
}
result[i+1]='\0';
printf("\nResult as string: %s\n", result);
}
else printf("Error number %x.\n", GetLastError());
}