【发布时间】:2011-05-22 18:25:00
【问题描述】:
我有一个棘手的问题,我希望我能解释清楚, 我想从 Windows 注册表中读取值,该值由另一个我没有源代码的程序保存,但我已经知道这个值的类型,它是这样的:
_MyData = record
byteType: Byte;
encData: PByte;
end;
byteType 表示这个数据的类型为整数(1,2,3…)你可以忽略这个参数,而encData是使用windows加密的数据crypt32.dll 函数 (CryptProtectData) 我使用下一个代码从注册表中读取值:
procedure TForm1.Button2Click(Sender: TObject);
var
myData: _MyData;
reg: TRegistry;
valueSize: Integer;
begin
reg := TRegistry.Create;
try
if reg.OpenKey(KEY_PATH,false) then
Begin
valueSize := reg.GetDataSize(VALUE_NAME);
reg.ReadBinaryData(VALUE_NAME, myData, valueSize);
End;
finally
reg.Free;
end;
end;
// KEY_PATH, VALUE_NAME 是字符串常量。
所以,现在我在 myData.encData 中有加密数据,现在我想通过传递具有此签名的 CryptUnprotectData 函数对其进行解密:
function CryptUnprotectData(pDataIn: PDATA_BLOB; ppszDataDescr: PLPWSTR; pOptionalEntropy: PDATA_BLOB; pvReserved: Pointer; pPromptStruct: PCRYPTPROTECT_PROMPTSTRUCT; dwFlags: DWORD; pDataOut: PDATA_BLOB): BOOL; stdcall;
首先,我需要将加密数据放入一个具有以下结构的 DATA_BLOB 类型的变量中:
_CRYPTOAPI_BLOB = record
cbData: DWORD;
pbData: PBYTE;
end;
DATA_BLOB = _CRYPTOAPI_BLOB;
PDATA_BLOB = ^DATA_BLOB;
pbData 是指向加密数据的指针(我是从注册表中读取的),cbData 是加密数据的大小,这是我的问题 我有myData.encData 中指向加密数据的指针(我已经从注册表中读取了它),它是 PByte,但我不知道如何获取这些数据的大小?如果我没有给函数 CryptUnprotectData 提供正确的大小,它总是在输出中给出 nil,知道该怎么做吗?
感谢您的帮助。
编辑:解决方案,感谢 Ken Bourassa
_MyData = packed record
byteType: Byte;
encData: array of byte;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
myData: ^_MyData;
reg: TRegistry;
valueSize: Integer;
dataIn, dataOut: DATA_BLOB;
begin
reg := TRegistry.Create;
try
if reg.OpenKey(KEY_PATH,false) then
Begin
valueSize := reg.GetDataSize(VALUE_NAME);
GetMem(myData, ValueSize);
try
reg.ReadBinaryData(VALUE_NAME, myData^, valueSize);
dataOut.cbData := 0;
dataOut.pbData := nil;
dataIn.cbData := Valuesize - SizeOf(Byte);
dataIn.pbData := @myData.encData;
CryptUnprotectData(@dataIn,nil,nil,nil,nil,CRYPTPROTECT_UI_FORBIDDEN,@dataOut);
//yes, it works, Thank you very much Ken Bourassa
finally
FreeMem(myData);
End;
End;
finally
reg.Free;
end;
end;
【问题讨论】:
-
你从注册表中究竟读到了什么,这不就是 CRYPTOAPI_BLOB 记录吗?如果不是,数据在写入之前是否被修改过(例如序列化、某种 bintohex 等)?
-
我想知道你怎么没有
reg.Create.. -
@Sertac Akyuz 是的,你是对的,这是紧急任务 :) 它应该是 reg := TRegistry.Create;
标签: delphi pointers cryptography encryption