C++解密Chrome80版本数据库的方法示例代码

2020-05-06 13:59:02王振洲

一般来说 安装的这些配置文件都在LOCAL_APPDATA下。可以使用SHGetSpecialFolderPath(NULL, szBuffer, CSIDL_LOCAL_APPDATA, FALSE);

来获取这个路径。然后starcat组合一下字符串得到路径 部分代码如下:

 char szBuffer[MAX_PATH];
	if (EncryptBaseKey == "")
	{
		string jsonstr;
		SHGetSpecialFolderPath(NULL, szBuffer, CSIDL_LOCAL_APPDATA, FALSE);
		strcat(szBuffer, "GoogleChromeUser DataLocal State");
		jsonstr = readfile(szBuffer);
		Document root;
		root.Parse(jsonstr.c_str());
		Value& infoArray = root["os_crypt"];
		EncryptBaseKey = infoArray["encrypted_key"].GetString();
	}
	return EncryptBaseKey;

这里就获取了加密的秘钥。但是有一点。如果是非80版本 是不存在os_crypt的,这里使用的rapidjson就会抛出异常。但不影响。只需要在使用sqllite查询的时候 接管一下字符串,看看是不是包含v10或者v11即可。如果你使用的和我一样代码。请注意大小写V10和v10的区别。

 string e_str = argv[i];
			if (strstr(e_str.c_str(), "v10") != NULL || strstr(e_str.c_str(), "v11") != NULL)
			{
				string DecryptVaule=NewDecrypt(argv[i]);
				strcpy(enc_value_a, DecryptVaule.c_str());
			}
			else{
				DecryptPass(argv[i], enc_value, 2048);
				_snprintf_s(enc_value_a, sizeof(enc_value_a), _TRUNCATE, "%S", enc_value);
			}

紧接着就是对他进行base64解密。这里我用的是cryptopp  先放一下新版解密函数

std::string static NewDecrypt(CHAR *cryptData)
{
	string EncryptValue = cryptData;
	string Encoded,Decoded;
	string key,iv,chiper;
	string recovered;//也就是解密的KEY
	WCHAR enc_value[2048];
	char enc_value_a[2048];

	ZeroMemory(enc_value, sizeof(enc_value));
	ZeroMemory(enc_value_a, sizeof(enc_value_a));
	//-----------------------初始化几个要用到加密字符串的变量----------------------------------//
	iv = EncryptValue;
	chiper = EncryptValue;
	//---------------------------------------------------------//
	StringSource((BYTE*)EncryptValue.c_str(), EncryptValue.size(), true,
		new HexEncoder(
		new StringSink(Encoded)));
	EncryptValue = Encoded;
	Encoded.clear();
	//---------------------------------------------------------//
	key = GetEncryptKEY();
	StringSource((BYTE*)key.c_str(), key.size(), true,
		new Base64Decoder(
		new StringSink(Decoded)));
	key = Decoded;
	key = key.substr(5);//去除首位5个字符
	Decoded.clear();
	DecryptPass((char*)key.c_str(), enc_value, 2048);
	_snprintf_s(enc_value_a, sizeof(enc_value_a), _TRUNCATE, "%S", enc_value);
	key = enc_value_a;
	StringSource((BYTE*)key.c_str(),key.size(), true,
		new HexEncoder(
		new StringSink(Encoded)));
	key = Encoded;
	Encoded.clear();
	//KEY解密完毕 开始处理Nonce 也就是IV
	iv =iv.substr(3,12);
	StringSource((BYTE*)iv.c_str(), iv.size(), true,
		new HexEncoder(
		new StringSink(Encoded)));
	iv = Encoded;
	Encoded.clear();
	//---------------------------------------------------------//
	//开始处理chiper
	if (chiper.size() < 30){ return "wu xiao zi fu chuan....."; }
	StringSource((BYTE*)chiper.c_str(), chiper.size(), true,
		new HexEncoder(
		new StringSink(Encoded)));
	chiper = Encoded;
	Encoded.clear();
	chiper = chiper.substr(30);//因为是HEX 占了2个字节
	//---------------------------------------------------------//
	//进行AES_GCM
	try
	{
		StringSource((BYTE*)iv.c_str(), iv.size(), true,
			new HexDecoder(
			new StringSink(Decoded)
			) // HexEncoder
			); // StringSource
		iv = Decoded;
		Decoded.clear();
		StringSource((BYTE*)key.c_str(), key.size(), true,
			new HexDecoder(
			new StringSink(Decoded)
			) // HexEncoder
			); // StringSource
		key = Decoded;
		Decoded.clear();
		StringSource((BYTE*)chiper.c_str(), chiper.size(), true,
			new HexDecoder(
			new StringSink(Decoded)
			) // HexEncoder
			); // StringSource
		chiper = Decoded;
		Decoded.clear();
		cout << chiper << endl;
		GCM< AES >::Decryption d;
		d.SetKeyWithIV((BYTE*)key.c_str(), key.size(), (BYTE*)iv.c_str(), iv.size());
		StringSource s(chiper, true,
			new AuthenticatedDecryptionFilter(d,
			new StringSink(recovered)
			) // StreamTransformationFilter
			); // StringSource
		cout << "recovered text: " << recovered << endl;
	}
	catch (const CryptoPP::Exception& e)
	{
		cerr << e.what() << endl;
		//exit(1);
	}
	return recovered;
}