-
Есть ПО, состоящее из двух исполняемых файлов. Возникла необходимость проверить цифровую подпись одного из них другим. С самой проверкой проблемы быть не должно, в сети полно примеров, например, https://msdn.microsoft.com/en-us/library/aa382384Вопрос, собственно, о подводных камнях, к тем кто сталкивался с такими проверками в реальной жизни. Может ли возникнуть такая ситуация, что, по какой-то причине, валидная подпись будет определяться не валидной? Т.е. какова надежность данного механизма проверки (через WinVerifyTrust)? Не поломается ли оно на каких-то машинах с определенными настройками ОС?
-
Есть ПО, состоящее из двух исполняемых файлов. Возникла необходимость проверить цифровую подпись одного из них другим. С самой проверкой проблемы быть не должно, в сети полно примеров, например, https://msdn.microsoft.com/en-us/library/aa382384Вопрос, собственно, о подводных камнях, к тем кто сталкивался с такими проверками в реальной жизни. Может ли возникнуть такая ситуация, что, по какой-то причине, валидная подпись будет определяться не валидной? Т.е. какова надежность данного механизма проверки (через WinVerifyTrust)? Не поломается ли оно на каких-то машинах с определенными настройками ОС?
-
Есть ПО, состоящее из двух исполняемых файлов. Возникла необходимость проверить цифровую подпись одного из них другим. С самой проверкой проблемы быть не должно, в сети полно примеров, например, https://msdn.microsoft.com/en-us/library/aa382384Вопрос, собственно, о подводных камнях, к тем кто сталкивался с такими проверками в реальной жизни. Может ли возникнуть такая ситуация, что, по какой-то причине, валидная подпись будет определяться не валидной? Т.е. какова надежность данного механизма проверки (через WinVerifyTrust)? Не поломается ли оно на каких-то машинах с определенными настройками ОС?
-
Есть ПО, состоящее из двух исполняемых файлов. Возникла необходимость проверить цифровую подпись одного из них другим. С самой проверкой проблемы быть не должно, в сети полно примеров, например, https://msdn.microsoft.com/en-us/library/aa382384Вопрос, собственно, о подводных камнях, к тем кто сталкивался с такими проверками в реальной жизни. Может ли возникнуть такая ситуация, что, по какой-то причине, валидная подпись будет определяться не валидной? Т.е. какова надежность данного механизма проверки (через WinVerifyTrust)? Не поломается ли оно на каких-то машинах с определенными настройками ОС?
-
Есть ПО, состоящее из двух исполняемых файлов. Возникла необходимость проверить цифровую подпись одного из них другим. С самой проверкой проблемы быть не должно, в сети полно примеров, например, https://msdn.microsoft.com/en-us/library/aa382384Вопрос, собственно, о подводных камнях, к тем кто сталкивался с такими проверками в реальной жизни. Может ли возникнуть такая ситуация, что, по какой-то причине, валидная подпись будет определяться не валидной? Т.е. какова надежность данного механизма проверки (через WinVerifyTrust)? Не поломается ли оно на каких-то машинах с определенными настройками ОС?
-
> Вопрос, собственно, о подводных камнях, к тем кто сталкивался > с такими проверками в реальной жизни. Может ли возникнуть > такая ситуация, что, по какой-то причине, валидная подпись > будет определяться не валидной?
Есть конечно, если каталог с подписями снесен - все родные файлы (в особенности дрова) ОС будут без подписи ибо она не помещена у них в тело PE файла. А так вроде бы других ошибок за последние 10 лет (или когда мы там цифровую то повесили, запямятовал уже) не встречал.
-
> Вопрос, собственно, о подводных камнях, к тем кто сталкивался > с такими проверками в реальной жизни. Может ли возникнуть > такая ситуация, что, по какой-то причине, валидная подпись > будет определяться не валидной?
Есть конечно, если каталог с подписями снесен - все родные файлы (в особенности дрова) ОС будут без подписи ибо она не помещена у них в тело PE файла. А так вроде бы других ошибок за последние 10 лет (или когда мы там цифровую то повесили, запямятовал уже) не встречал.
-
Кстати в твоем примере самый простейший вариант и на системных файлах не отработает, нужно каталоги подключать. примерно так:
const WTD_CHOICE_FILE = 1; WTD_CHOICE_CATALOG = 2; WTD_STATEACTION_IGNORE = 0; WTD_STATEACTION_VERIFY = 1; WTD_UI_NONE = 2; WTD_REVOKE_NONE = 0; WTD_SAFER_FLAG = 256; WINTRUST_ACTION_GENERIC_VERIFY_V2: TGUID = '{00AAC56B-CD44-11d0-8CC2-00C04FC295EE}'; WINTRUST_ACTION_GENERIC_VERIFY_V7: TGUID = '{F750E6C3-38EE-11D1-85E5-00C04FC295EE}';
type CATALOG_INFO = record cbStruct: DWORD; // = sizeof(WINTRUST_CATALOG_INFO) sCatalogFile: array[0..MAX_PATH] of WCHAR; end; PCATALOG_INFO = ^CATALOG_INFO;
WINTRUST_CATALOG_INFO = record cbStruct: DWORD; // = sizeof(WINTRUST_CATALOG_INFO) dwCatalogVersion: DWORD; pcwszCatalogFilePath: LPCWSTR; pcwszMemberTag: LPCWSTR; pcwszMemberFilePath: LPCWSTR; hMemberFile: THANDLE; end; PWINTRUST_CATALOG_INFO = ^WINTRUST_CATALOG_INFO;
WINTRUST_FILE_INFO = record cbStruct: DWORD; // = sizeof(WINTRUST_FILE_INFO) pcwszFilePath: LPCWSTR; pgKnownSubject: PGUID; hFile: THANDLE; end; PWINTRUST_FILE_INFO = ^WINTRUST_FILE_INFO;
WINTRUST_DATA = packed record cbStruct: DWORD; // = sizeof(WINTRUST_DATA) pPolicyCallbackData: pointer; pSIPClientData: pointer; dwUIChoice: DWORD; fdwRevocationChecks: DWORD; dwUnionChoice: DWORD; pWTDINFO: pointer; pFake: pointer; pFake1: pointer; pFake2: pointer; pFake3: pointer; dwStateAction: DWORD; hWVTStateData: THANDLE; pwszURLReference: PWChar; dwProvFlags: DWORD; dwUIContext: DWORD; end; PWINTRUST_DATA = ^WINTRUST_DATA; HCatAdmin = THANDLE; PHCatAdmin = ^HCatAdmin;
var hLibWintrust: THandle; 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;
function CheckFileTrust(const sFilename: string): Boolean; var 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; x : Integer; begin Result := False; if not FileExists(sFilename) then Exit; swFilename := sFilename; ZeroMemory(@CatalogInfo, SizeOf(CatalogInfo)); ZeroMemory(@WTDFileInfo, SizeOf(WTDFileInfo)); ZeroMemory(@WTDCatalogInfo, SizeOf(WTDCatalogInfo)); ZeroMemory(@WTrustData, SizeOf(WTrustData)); if CryptCATAdminAcquireContext(@hCatAdminContext, nil, 0) = False then Exit; hFile := CreateFile(PChar(string(sFilename)), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if hFile = INVALID_HANDLE_VALUE then Exit; iByteCount := SizeOf(aByteHash); CryptCATAdminCalcHashFromFileHandle(hFile, @iByteCount, @aByteHash, 0); for x := 0 to iByteCount - 1 do swMemberTag := swMemberTag + IntToHex(aByteHash[x], 2); CloseHandle(hFile); hCatalogContext := CryptCATAdminEnumCatalogFromHash(hCatAdminContext, @aByteHash, iByteCount, 0, nil); if hCatalogContext = 0 then begin WTDFileInfo.cbStruct := SizeOf(WTDFileInfo); WTDFileInfo.pcwszFilePath := PWideChar(swFilename); WTDFileInfo.pgKnownSubject := nil; WTDFileInfo.hFile := 0; WTrustData.cbStruct := SizeOf(WTrustData); WTrustData.dwUnionChoice := WTD_CHOICE_FILE; WTrustData.pWTDINFO := @WTDFileInfo; WTrustData.dwUIChoice := WTD_UI_NONE; WTrustData.fdwRevocationChecks := WTD_REVOKE_NONE; WTrustData.dwStateAction := WTD_STATEACTION_IGNORE; WTrustData.dwProvFlags := WTD_SAFER_FLAG; WTrustData.hWVTStateData := 0; WTrustData.pwszURLReference := nil; end else begin CryptCATCatalogInfoFromContext(hCatalogContext, @CatalogInfo, 0); WTDCatalogInfo.cbStruct := SizeOf(WTDCatalogInfo); WTDCatalogInfo.pcwszCatalogFilePath := CatalogInfo.sCatalogFile; WTDCatalogInfo.pcwszMemberFilePath := PWideChar(swFilename); WTDCatalogInfo.pcwszMemberTag := PWideChar(swMemberTag); WTrustData.cbStruct := SizeOf(WTrustData); WTrustData.dwUnionChoice := WTD_CHOICE_CATALOG; WTrustData.pWTDINFO := @WTDCatalogInfo; WTrustData.dwUIChoice := WTD_UI_NONE; WTrustData.fdwRevocationChecks := WTD_REVOKE_NONE; WTrustData.pPolicyCallbackData := nil; WTrustData.pSIPClientData := nil; WTrustData.dwStateAction := WTD_STATEACTION_VERIFY; WTrustData.dwProvFlags := 0; WTrustData.hWVTStateData := 0; WTrustData.pwszURLReference := nil; end; Result := WinVerifyTrust(INVALID_HANDLE_VALUE, @WINTRUST_ACTION_GENERIC_VERIFY_V2, @WTrustData) = 0; if not Result then Result := WinVerifyTrust(INVALID_HANDLE_VALUE, @WINTRUST_ACTION_GENERIC_VERIFY_V7, @WTrustData) = 0; CryptCATAdminReleaseCatalogContext(hCatAdminContext, hCatalogContext, 0); CryptCATAdminReleaseContext(hCatAdminContext, 0); end;
-
Кстати в твоем примере самый простейший вариант и на системных файлах не отработает, нужно каталоги подключать. примерно так:
const WTD_CHOICE_FILE = 1; WTD_CHOICE_CATALOG = 2; WTD_STATEACTION_IGNORE = 0; WTD_STATEACTION_VERIFY = 1; WTD_UI_NONE = 2; WTD_REVOKE_NONE = 0; WTD_SAFER_FLAG = 256; WINTRUST_ACTION_GENERIC_VERIFY_V2: TGUID = '{00AAC56B-CD44-11d0-8CC2-00C04FC295EE}'; WINTRUST_ACTION_GENERIC_VERIFY_V7: TGUID = '{F750E6C3-38EE-11D1-85E5-00C04FC295EE}';
type CATALOG_INFO = record cbStruct: DWORD; // = sizeof(WINTRUST_CATALOG_INFO) sCatalogFile: array[0..MAX_PATH] of WCHAR; end; PCATALOG_INFO = ^CATALOG_INFO;
WINTRUST_CATALOG_INFO = record cbStruct: DWORD; // = sizeof(WINTRUST_CATALOG_INFO) dwCatalogVersion: DWORD; pcwszCatalogFilePath: LPCWSTR; pcwszMemberTag: LPCWSTR; pcwszMemberFilePath: LPCWSTR; hMemberFile: THANDLE; end; PWINTRUST_CATALOG_INFO = ^WINTRUST_CATALOG_INFO;
WINTRUST_FILE_INFO = record cbStruct: DWORD; // = sizeof(WINTRUST_FILE_INFO) pcwszFilePath: LPCWSTR; pgKnownSubject: PGUID; hFile: THANDLE; end; PWINTRUST_FILE_INFO = ^WINTRUST_FILE_INFO;
WINTRUST_DATA = packed record cbStruct: DWORD; // = sizeof(WINTRUST_DATA) pPolicyCallbackData: pointer; pSIPClientData: pointer; dwUIChoice: DWORD; fdwRevocationChecks: DWORD; dwUnionChoice: DWORD; pWTDINFO: pointer; pFake: pointer; pFake1: pointer; pFake2: pointer; pFake3: pointer; dwStateAction: DWORD; hWVTStateData: THANDLE; pwszURLReference: PWChar; dwProvFlags: DWORD; dwUIContext: DWORD; end; PWINTRUST_DATA = ^WINTRUST_DATA; HCatAdmin = THANDLE; PHCatAdmin = ^HCatAdmin;
var hLibWintrust: THandle; 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;
function CheckFileTrust(const sFilename: string): Boolean; var 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; x : Integer; begin Result := False; if not FileExists(sFilename) then Exit; swFilename := sFilename; ZeroMemory(@CatalogInfo, SizeOf(CatalogInfo)); ZeroMemory(@WTDFileInfo, SizeOf(WTDFileInfo)); ZeroMemory(@WTDCatalogInfo, SizeOf(WTDCatalogInfo)); ZeroMemory(@WTrustData, SizeOf(WTrustData)); if CryptCATAdminAcquireContext(@hCatAdminContext, nil, 0) = False then Exit; hFile := CreateFile(PChar(string(sFilename)), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if hFile = INVALID_HANDLE_VALUE then Exit; iByteCount := SizeOf(aByteHash); CryptCATAdminCalcHashFromFileHandle(hFile, @iByteCount, @aByteHash, 0); for x := 0 to iByteCount - 1 do swMemberTag := swMemberTag + IntToHex(aByteHash[x], 2); CloseHandle(hFile); hCatalogContext := CryptCATAdminEnumCatalogFromHash(hCatAdminContext, @aByteHash, iByteCount, 0, nil); if hCatalogContext = 0 then begin WTDFileInfo.cbStruct := SizeOf(WTDFileInfo); WTDFileInfo.pcwszFilePath := PWideChar(swFilename); WTDFileInfo.pgKnownSubject := nil; WTDFileInfo.hFile := 0; WTrustData.cbStruct := SizeOf(WTrustData); WTrustData.dwUnionChoice := WTD_CHOICE_FILE; WTrustData.pWTDINFO := @WTDFileInfo; WTrustData.dwUIChoice := WTD_UI_NONE; WTrustData.fdwRevocationChecks := WTD_REVOKE_NONE; WTrustData.dwStateAction := WTD_STATEACTION_IGNORE; WTrustData.dwProvFlags := WTD_SAFER_FLAG; WTrustData.hWVTStateData := 0; WTrustData.pwszURLReference := nil; end else begin CryptCATCatalogInfoFromContext(hCatalogContext, @CatalogInfo, 0); WTDCatalogInfo.cbStruct := SizeOf(WTDCatalogInfo); WTDCatalogInfo.pcwszCatalogFilePath := CatalogInfo.sCatalogFile; WTDCatalogInfo.pcwszMemberFilePath := PWideChar(swFilename); WTDCatalogInfo.pcwszMemberTag := PWideChar(swMemberTag); WTrustData.cbStruct := SizeOf(WTrustData); WTrustData.dwUnionChoice := WTD_CHOICE_CATALOG; WTrustData.pWTDINFO := @WTDCatalogInfo; WTrustData.dwUIChoice := WTD_UI_NONE; WTrustData.fdwRevocationChecks := WTD_REVOKE_NONE; WTrustData.pPolicyCallbackData := nil; WTrustData.pSIPClientData := nil; WTrustData.dwStateAction := WTD_STATEACTION_VERIFY; WTrustData.dwProvFlags := 0; WTrustData.hWVTStateData := 0; WTrustData.pwszURLReference := nil; end; Result := WinVerifyTrust(INVALID_HANDLE_VALUE, @WINTRUST_ACTION_GENERIC_VERIFY_V2, @WTrustData) = 0; if not Result then Result := WinVerifyTrust(INVALID_HANDLE_VALUE, @WINTRUST_ACTION_GENERIC_VERIFY_V7, @WTrustData) = 0; CryptCATAdminReleaseCatalogContext(hCatAdminContext, hCatalogContext, 0); CryptCATAdminReleaseContext(hCatAdminContext, 0); end;
-
> Rouse_ © (10.04.17 21:09) [1]
> Есть конечно, если каталог с подписями снесен - все родные > файлы (в особенности дрова) ОС будут без подписи ибо она > не помещена у них в тело PE файла.
требуется проверять только свои файлы.
> А так вроде бы других ошибок за последние 10 лет (или когда > мы там цифровую то повесили, запямятовал уже) не встречал. >
это радует. будет пробовать внедрять проверку.
> Кстати в твоем примере самый простейший вариант и на системных > файлах не отработает, нужно каталоги подключать. примерно > так:
за пример на Делфи благодарю. что касается системных файлов, их проверка и не требуется.
-
> Rouse_ © (10.04.17 21:09) [1]
> Есть конечно, если каталог с подписями снесен - все родные > файлы (в особенности дрова) ОС будут без подписи ибо она > не помещена у них в тело PE файла.
требуется проверять только свои файлы.
> А так вроде бы других ошибок за последние 10 лет (или когда > мы там цифровую то повесили, запямятовал уже) не встречал. >
это радует. будет пробовать внедрять проверку.
> Кстати в твоем примере самый простейший вариант и на системных > файлах не отработает, нужно каталоги подключать. примерно > так:
за пример на Делфи благодарю. что касается системных файлов, их проверка и не требуется.
-
> Eraser © (10.04.17 20:57)
> Вопрос, собственно, о подводных камнях, к тем кто сталкивался > с такими проверками в реальной жизни. Может ли возникнуть > такая ситуация, что, по какой-то причине, валидная подпись > будет определяться не валидной? Т.е. какова надежность данного > механизма проверки (через WinVerifyTrust)? Не поломается > ли оно на каких-то машинах с определенными настройками ОС? >
Может. Если в системе есть зловреды, подменившие корневые сертификаты.
-
> Eraser © (10.04.17 20:57)
> Вопрос, собственно, о подводных камнях, к тем кто сталкивался > с такими проверками в реальной жизни. Может ли возникнуть > такая ситуация, что, по какой-то причине, валидная подпись > будет определяться не валидной? Т.е. какова надежность данного > механизма проверки (через WinVerifyTrust)? Не поломается > ли оно на каких-то машинах с определенными настройками ОС? >
Может. Если в системе есть зловреды, подменившие корневые сертификаты.
-
еще выяснился такой момент, что без интернета и апдейтов современные sha256 сертификаты работают из коробки только начиная с 7, но в принципе, этого достаточно.
-
еще выяснился такой момент, что без интернета и апдейтов современные sha256 сертификаты работают из коробки только начиная с 7, но в принципе, этого достаточно.
-
Да вроде нет такого, как проверял? Линк ка экзешник дай, проверю на тестовой вм
-
Да вроде нет такого, как проверял? Линк ка экзешник дай, проверю на тестовой вм
-
> Rouse_ © (19.04.17 20:18) [6]
_remoteutilities.com/download/agent.exe
на висте sp0 не работает. Нет доверия к этому корневому сертификату центра сертификации, поскольку он не найден в хранилище доверенных корневых сертификатов центров сертификации.
ну с xp все понятно, там его вообще поврежденным считают.
-
> Rouse_ © (19.04.17 20:18) [6]
_remoteutilities.com/download/agent.exe
на висте sp0 не работает. Нет доверия к этому корневому сертификату центра сертификации, поскольку он не найден в хранилище доверенных корневых сертификатов центров сертификации.
ну с xp все понятно, там его вообще поврежденным считают.
-
> Eraser © (19.04.17 15:32) [5] > еще выяснился такой момент
ну т.е. раньше на это можно было не обращать внимания, что я успешно и делал, как оно там на старых ОС. тогда как в случае самостоятельной проверки внутри софта такие моменты нужно учитывать.
-
> Eraser © (19.04.17 15:32) [5] > еще выяснился такой момент
ну т.е. раньше на это можно было не обращать внимания, что я успешно и делал, как оно там на старых ОС. тогда как в случае самостоятельной проверки внутри софта такие моменты нужно учитывать.
-
В случае самостоятельной проверки внутри софта лучше проверять своими средствами, не полагаясь на ос. А еще лучше и то и другое. Ну и корневые свои с собой таскать не плохо бы, но запрятать куда нибудь.
-
В случае самостоятельной проверки внутри софта лучше проверять своими средствами, не полагаясь на ос. А еще лучше и то и другое. Ну и корневые свои с собой таскать не плохо бы, но запрятать куда нибудь.
-
> DVM © (20.04.17 08:01) [9]
ну если зловред подменит корневые, значит так тому и быть. у меня основная задача, чтобы "сборщики" не использовали наше ПО в качестве вредоносного, не внося каких-либо изменений в код или ОС. патчи, лоадеры и прочие дропперы, оставляем пока на совести антивирусов. они довольно не плохо справляются.
-
> DVM © (20.04.17 08:01) [9]
ну если зловред подменит корневые, значит так тому и быть. у меня основная задача, чтобы "сборщики" не использовали наше ПО в качестве вредоносного, не внося каких-либо изменений в код или ОС. патчи, лоадеры и прочие дропперы, оставляем пока на совести антивирусов. они довольно не плохо справляются.
|