2017-10-18 8 views
0

私はChromeからパスワードを取得するリカバリアプリを作成しています。それはGUIを持っているので、SQLConnectionとSQLQueryの両方を使用するSQLiteラッパーを使用しました。ここに私のコードのスニップです:CryptUnprotectDataを含むRAD Studio CreateBlobStreamが余分な文字を返すのはなぜですか?

//Create our blob stream 
TStream *Stream2 = SQLQuery1->CreateBlobStream(SQLQuery1->FieldByName("password_value"), bmRead); 
//Get our blob size 
int size = Stream2->Size; 
//Create our buffer 
char* pbDataInput = new char[size+1]; 
//Adding null terminator to buffer 
memset(pbDataInput, 0x00, sizeof(char)*(size+1)); 
//Write to our buffer 
Stream2->ReadBuffer(pbDataInput, size); 
DWORD cbDataInput = size; 

DataOut.pbData = pbDataInput; 
DataOut.cbData = cbDataInput; 

LPWSTR pDescrOut = NULL; 
//Decrypt password 
CryptUnprotectData(&DataOut, 
     &pDescrOut, 
     NULL, 
     NULL, 
     NULL, 
     0, 
     &DataVerify); 

//Output password 
UnicodeString password = (UnicodeString)(char*)DataVerify.pbData; 
passwordgrid->Cells[2][i] = password; 

出力データは、何かが私のヌルターミネータと間違っていたかのように振る舞うを除いて、正常に見えます。ここでは、出力はすべての行に次のようになります。私が読んだ

Output Data With Extra Chars at end of Password

CryptUnprotectDataため

Windowsのドキュメント:

https://msdn.microsoft.com/en-us/library/windows/desktop/aa382377.aspx

CreateBlobStreamため

エンバカデロのドキュメント:

http://docwiki.embarcadero.com/Libraries/en/Data.DB.TDataSet.CreateBlobStream

のmemset:

http://www.cplusplus.com/reference/cstring/memset/

答えて

1

あなたの読書との通話を解読するだけ生のバイトで動作する、彼らは文字列について何も知らないし、それを気にしないでください。あなたはpbDataInputに追加するNULL終止符が使用されることはありませんので、それを取り除く:

//Get our blob size 
int size = Stream2->Size; 
//Create our buffer 
char* pbDataInput = new char[size]; 
//Write to our buffer 
Stream2->ReadBuffer(pbDataInput, size); 
DWORD cbDataInput = size; 
... 
delete[] pbDataInput; 
delete Stream2; 

passwordからpbDataを割り当てるとき、あなたはchar*pbDataをキャストしているので、UnicodeStringコンストラクタは、データを解釈しますヌルで終了するANSI文字列を返し、システムのデフォルトのANSIコードページを使用してUTF-16に変換します。これは、ASCII以外の文字に対しては不可逆変換である可能性があります。あなたが本当に欲しいのはそれですか?

もしそうなら、及び復号化されたデータが実際にnull終端されていない場合は、UnicodeStringコンストラクタに文字の数を指定する必要があります。復号化された出力が既にある場合、一方

UnicodeString password((char*)DataVerify.pbData, DataVerify.cbData); 

UTF-16で、あなたの代わりにwchar_t*pbDataをキャストする必要があります。

UnicodeString password = (wchar_t*)DataVerify.pbData; 

または、NULL終端されていない場合:

UnicodeString password((wchar_t*)DataVerify.pbData, DataVerify.cbData/sizeof(wchar_t)); 
+0

ありがとう、私はそれがヌルターミネーターと何か関係がありました。あなたの答えをアップアップする。 –

関連する問題