delphi 验证文件签名


本文整理自网络,侵删。

 delphi 验证文件签名

unit uSimpleTrustCheck;

interface

function CheckFileTrust(const sFilename: string): Boolean;

implementation

uses
Windows,
SysUtils;

const
//Kostanten für die dwUnionChoice in WINTRUST_DATA
WTD_CHOICE_FILE = 1;
WTD_CHOICE_CATALOG = 2;

//Konstanten für dwStateAction
WTD_STATEACTION_IGNORE = 0;
WTD_STATEACTION_VERIFY = 1;

//UI Konstanten für WINTRUST_DATA
WTD_UI_NONE = 2; //kein UI anzeigen

//Konstanten zur Prüfung auf zurückgezogene Zertifikate
WTD_REVOKE_NONE = 0; // keine zus?tzliche Prüfun

//Konstanten für TrustProvider
WTD_SAFER_FLAG = 256; // für Winxp Sp2 ben?tigt

//Wintrust Action GUID′s
WINTRUST_ACTION_GENERIC_VERIFY_V2: TGUID = '{00AAC56B-CD44-11d0-8CC2-00C04FC295EE}';


type

CATALOG_INFO = record
cbStruct: DWORD; // = sizeof(WINTRUST_CATALOG_INFO)
sCatalogFile: array[0..MAX_PATH] of WCHAR; // Dateiname incl. Pfad zur CAT Datei
end;
PCATALOG_INFO = ^CATALOG_INFO;


WINTRUST_CATALOG_INFO = record
cbStruct: DWORD; // = sizeof(WINTRUST_CATALOG_INFO)
dwCatalogVersion: DWORD; // optional
pcwszCatalogFilePath: LPCWSTR; // ben?tigt, Dateiname incl. Pfad zur CAT Datei
pcwszMemberTag: LPCWSTR; // ben?tigt, tag zum Mitglied im Katalog
pcwszMemberFilePath: LPCWSTR; // ben?tigt, Dateiname incl. Pfad
hMemberFile: THANDLE; // optional
end;
PWINTRUST_CATALOG_INFO = ^WINTRUST_CATALOG_INFO;


WINTRUST_FILE_INFO = record
cbStruct: DWORD; // = sizeof(WINTRUST_FILE_INFO)
pcwszFilePath: LPCWSTR; // ben?tigt, Dateiname incl. Pfad
pgKnownSubject: PGUID; // optional
hFile: THANDLE; // optional
end;
PWINTRUST_FILE_INFO = ^WINTRUST_FILE_INFO;


WINTRUST_DATA = packed record
cbStruct: DWORD; // = sizeof(WINTRUST_DATA)
pPolicyCallbackData: pointer; // optional - auf 0 setzen
pSIPClientData: pointer; // optional - auf 0 setzen
dwUIChoice: DWORD; // ben?tigt, UI auswahl
fdwRevocationChecks: DWORD; // ben?tigt, auf zurückgezogene Zertifikate prüfen (online ben.)
dwUnionChoice: DWORD; // ben?tigt, welche Datenstruktur soll verwendet werden
pWTDINFO: pointer; // Pointer zu einer der Wintrust_X_Info Strukturen
pFake: pointer; //Fake Pointer - n?tig damit der Speicer wieder freigegeben wird
pFake1: pointer; //Fake Pointer - n?tig damit der Speicer wieder freigegeben wird
pFake2: pointer; //Fake Pointer - n?tig damit der Speicer wieder freigegeben wird
pFake3: pointer; //Fake Pointer - n?tig damit der Speicer wieder freigegeben wird
dwStateAction: DWORD;
hWVTStateData: THANDLE;
pwszURLReference: PWChar;
dwProvFlags: DWORD;
dwUIContext: DWORD;

end;
PWINTRUST_DATA = ^WINTRUST_DATA;

//Handle und Pointer auf KatalogAdminKontext
HCatAdmin = THANDLE;
PHCatAdmin = ^HCatAdmin;


var
hLibWintrust : THANDLE;

//dynamische Dll Aufrufe - keine Statische einbindung m?glich
CryptCATAdminAcquireContext : function(PHCatAdmin: PHCatAdmin; pgSubsystem: PGUID; dwFlags: DWORD): BOOL; stdcall;
CryptCATAdminReleaseContext : function(HCatAdmin: HCatAdmin; dwFlags: DWORD): BOOL; stdcall;
CryptCATAdminCalcHashFromFileHandle: function(hFile: THANDLE; pHashSize: PDWORD; pbHash: PByteArray; dwFlags: DWORD): BOOL; stdcall;
CryptCATAdminEnumCatalogFromHash: function(HCatAdmin: HCatAdmin; pbHash: PByteArray; pHashSize: DWORD; dwFlags: DWORD; phPrevCatInfo: PHandle): THANDLE; stdcall;
CryptCATCatalogInfoFromContext: function(hCatInfo: THANDLE; psCatInfo: PCATALOG_INFO; dwFlags: DWORD): BOOL; stdcall;
CryptCATAdminReleaseCatalogContext: function(HCatAdmin: HCatAdmin; hCatInfo: THANDLE; dwFlags: DWORD): BOOL; stdcall;
WinVerifyTrust : function(hwnd: THANDLE; pgActionID: PGUID; pWintrustData: PWINTRUST_DATA): Longint; stdcall;





{-----------------------------------------------------------------------------
Funcktion: CheckFileTrust
Date: 02-Mrz-2005
Arguments: const sFilename: string
Result: Boolean
Description: Prüft ob die angegebene Datei Trusted ist
-----------------------------------------------------------------------------}
function CheckFileTrust(const sFilename: string): Boolean;
var
//Byte Array und Counter
aByteHash : array[0..255] of Byte;
iByteCount : Integer;

hCatAdminContext : HCatAdmin;
WTrustData : WINTRUST_DATA;
WTDCatalogInfo : WINTRUST_CATALOG_INFO;
WTDFileInfo : WINTRUST_FILE_INFO;
CatalogInfo : CATALOG_INFO;

hFile : THANDLE;
hCatalogContext : THANDLE;

swFilename : WideString;
swMemberTag : WideString;

ilRet : Longint;
x : Integer;

begin

//Standard Result setzen
Result := False;

//Sicherheitsabfrage ob Datei existiert
if FileExists(sFilename) = False then Exit;

//String in Widestring wandeln
swFilename := sFilename;


ZeroMemory(@CatalogInfo, SizeOf(CatalogInfo));
ZeroMemory(@WTDFileInfo, SizeOf(WTDFileInfo));
ZeroMemory(@WTDCatalogInfo, SizeOf(WTDCatalogInfo));
ZeroMemory(@WTrustData, SizeOf(WTrustData));


//Catalog Admin Kontext ?ffnen und falls nicht m?glich Prozedur verlassen
if CryptCATAdminAcquireContext(@hCatAdminContext, nil, 0) = False then Exit;


//Filehandle auf die zu prüfende Datei holen
hFile := CreateFile(PChar(string(sFilename)), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

//Wenn das Handle nicht erhalten wurde Prozedur verlassen
if hFile = INVALID_HANDLE_VALUE then Exit;


//iaBytescount nach gr??e des Arrays setzen
iByteCount := SizeOf(aByteHash);

//ByteArray mit Hash füllen lassen und die Gr??e in iByteCount bekommen
CryptCATAdminCalcHashFromFileHandle(hFile, @iByteCount, @aByteHash, 0);

// MemberTag brechnen (vom ByteArray auf HEX)
for x := 0 to iByteCount - 1 do
begin
swMemberTag := swMemberTag + IntToHex(aByteHash[x], 2);
end;

//FileHandle schlie?en - wird nicht mehr gebraucht
CloseHandle(hFile);


//Erste Prüfung erfolgt mit WINTRUST_DATA.dwUnionChoice := WTD_CHOICE_CATALOG;
//also muss WINTRUST_CATALOG_INFO gefüllt werden
//
//Handle auf den Katalog Kontext holen
hCatalogContext := CryptCATAdminEnumCatalogFromHash(hCatAdminContext, @aByteHash, iByteCount, 0, nil);

//Wenn das Handle 0 ist muss die Prüfung mit der
//WINTRUST_DATA.dwUnionChoice := WTD_CHOICE_FILE; Struktur durchgeführt werden
if hCatalogContext = 0 then
begin
//CatalogContext = 0 also
//
//WINTRUST_FILE_INFO Struktur initialisieren und füllen
WTDFileInfo.cbStruct := SizeOf(WTDFileInfo);
WTDFileInfo.pcwszFilePath := PWideChar(swFilename);
WTDFileInfo.pgKnownSubject := nil;
WTDFileInfo.hFile := 0;

//WINTRUST_DATA Struktur initialisieren und füllen
WTrustData.cbStruct := SizeOf(WTrustData);
WTrustData.dwUnionChoice := WTD_CHOICE_FILE; //WINTRUST_FILE_INFO Struktur w?hlen
WTrustData.pWTDINFO := @WTDFileInfo; //Pointer zu WINTRUST_FILE_INFO
WTrustData.dwUIChoice := WTD_UI_NONE;
WTrustData.fdwRevocationChecks := WTD_REVOKE_NONE;
WTrustData.dwStateAction := WTD_STATEACTION_IGNORE;
WTrustData.dwProvFlags := WTD_SAFER_FLAG; //UI bei XP SP2 unterbinden
WTrustData.hWVTStateData := 0;
WTrustData.pwszURLReference := nil;
end
else
begin
//CatalogContext <> 0 also CATALOG_INFO benutzen
//
//CATALOG_INFO Struktur füllen
CryptCATCatalogInfoFromContext(hCatalogContext, @CatalogInfo, 0);

//WINTRUST_CATALOG_INFO Struktur initialisieren und füllen
WTDCatalogInfo.cbStruct := SizeOf(WTDCatalogInfo);
WTDCatalogInfo.pcwszCatalogFilePath := CatalogInfo.sCatalogFile;
WTDCatalogInfo.pcwszMemberFilePath := PWideChar(swFilename);
WTDCatalogInfo.pcwszMemberTag := PWideChar(swMemberTag);

//WINTRUST_DATA Struktur initialisieren und füllen
WTrustData.cbStruct := SizeOf(WTrustData);
WTrustData.dwUnionChoice := WTD_CHOICE_CATALOG; //WINTRUST_CATALOG_INFO Struktur w?hlen
WTrustData.pWTDINFO := @WTDCatalogInfo; //Pointer zu WINTRUST_CATALOG_INFO
WTrustData.dwUIChoice := WTD_UI_NONE;
WTrustData.fdwRevocationChecks := WTD_REVOKE_NONE;
WTrustData.pPolicyCallbackData := nil;
WTrustData.pSIPClientData := nil;
WTrustData.dwStateAction := WTD_STATEACTION_VERIFY;
WTrustData.dwProvFlags := 0; //WTD_SAFER_FLAG; //UI bei XP SP2 unterbinden
WTrustData.hWVTStateData := 0;
WTrustData.pwszURLReference := nil;
end;

//WinVerifyTrust aufrufen um die Prüfung durchzuführen
ilRet := WinVerifyTrust(INVALID_HANDLE_VALUE, @WINTRUST_ACTION_GENERIC_VERIFY_V2, @WTrustData);

//Wenn Erg. 0 ist dann ist das File Trusted - alle anderen Werte sind Fehlercodes
if ilRet = 0 then
begin
Result := True
end
else
Result := False;

//Handle zum Catalogfile schlie?en
CryptCATAdminReleaseCatalogContext(hCatAdminContext, hCatalogContext, 0);

//Catalog Admin Kontext schlie?en
CryptCATAdminReleaseContext(hCatAdminContext, 0);
end;



initialization
//Dynamisches laden der Dll und deren Funktionen
hLibWintrust := LoadLibrary('wintrust.dll');
if hLibWintrust >= 32 then { success }
begin
CryptCATAdminAcquireContext := GetProcAddress(hLibWintrust, 'CryptCATAdminAcquireContext');
CryptCATAdminReleaseContext := GetProcAddress(hLibWintrust, 'CryptCATAdminReleaseContext');
CryptCATAdminCalcHashFromFileHandle := GetProcAddress(hLibWintrust, 'CryptCATAdminCalcHashFromFileHandle');
CryptCATAdminEnumCatalogFromHash := GetProcAddress(hLibWintrust, 'CryptCATAdminEnumCatalogFromHash');
CryptCATCatalogInfoFromContext := GetProcAddress(hLibWintrust, 'CryptCATCatalogInfoFromContext');
CryptCATAdminReleaseCatalogContext := GetProcAddress(hLibWintrust, 'CryptCATAdminReleaseCatalogContext');
WinVerifyTrust := GetProcAddress(hLibWintrust, 'WinVerifyTrust');
end;

finalization
FreeLibrary(hLibWintrust);
end.

相关阅读 >>

Delphi 存储过程与函数的区别

Delphi fmx 把内容复制到粘贴板上支持跨平台

Delphi 中 unicode 转汉字 函数

Delphi操作多显示器

Delphi datetimetogmt gmt时间与tdatetime转换

Delphi二值图像腐蚀算法

Delphi 记录类型- 结构指针

Delphi 提取网页源文件纯文本函数

Delphi 获取listbox1的行值

Delphi webbrowser 实用代码收集

更多相关阅读请进入《Delphi》频道 >>



打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...