大佬教程收集整理的这篇文章主要介绍了windows – 从Delphi中以编程方式检查数字签名,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我已经看到了Microsoft’s example in C,但是如果别人已经有了,我不想浪费时间将其转换为Delphi。
// IsCodeSigned,which verifies that the exe hasn't been modified,uses // WinVerifyTrust,so it's NT only. IsCompanySigningCertificate works on Win9x,// but it only checks that the signing certificate hasn't been replaced,which // keeps someone from re-signing a modified executable. // Imagehlp.dll const CERT_SECTION_TYPE_ANY = $FF; // Any Certificate type function ImageEnumerateCertificates(FileHandle: THandle; TypeFilter: WORD; out CertificateCount: DWORD; InDicies: PDWORD; IndexCount: Integer): BOOL; stdcall; external 'Imagehlp.dll'; function ImageGetCertificateHeader(FileHandle: THandle; CertificateIndex: Integer; var CertificateHeader: TWinCertificatE): BOOL; stdcall; external 'Imagehlp.dll'; function ImageGetCertificateData(FileHandle: THandle; CertificateIndex: Integer; Certificate: PWinCertificate; var requiredLength: DWORD): BOOL; stdcall; external 'Imagehlp.dll'; // Crypt32.dll const CERt_name_SIMPLE_DISPLAY_TYPE = 4; PKCS_7_ASN_ENCODING = $00010000; X509_ASN_ENCODING = $00000001; type PCCERT_COntexT = type Pointer; HCRYPTPROV_LEGACY = type Pointer; PFN_CRYPT_GET_SIGNER_CERTIFICATE = type Pointer; CRYPT_VERIFY_messaGE_PARA = record cbSize: DWORD; dwMsgAndCertEncodingType: DWORD; hCryptProv: HCRYPTPROV_LEGACY; pfnGetSignerCertificate: PFN_CRYPT_GET_SIGNER_CERTIFICATE; pvGetArg: Pointer; end; function CryptVerifymessageSignature(const pVerifyPara: CRYPT_VERIFY_messaGE_PARA; dwSignerIndex: DWORD; pbSignedBlob: PByte; cbSignedBlob: DWORD; pbDecoded: PBYTE; pcbDecoded: PDWORD; ppSignerCert: PCCERT_COntexT): BOOL; stdcall; external 'Crypt32.dll'; function CertGetNameStringA(pCertContext: PCCERT_COntexT; dwType: DWORD; dwFlags: DWORD; pvTypePara: Pointer; pszNameString: PAnsiChar; cchNameString: DWORD): DWORD; stdcall; external 'Crypt32.dll'; function CertFreeCertificateContext(pCertContext: PCCERT_COntexT): BOOL; stdcall; external 'Crypt32.dll'; function CertCreateCertificateContext(dwCertEncodingType: DWORD; pbCertEncoded: PBYTE; cbCertEncoded: DWORD): PCCERT_COntexT; stdcall; external 'Crypt32.dll'; // WinTrust.dll const WINTRUST_ACTION_GENERIC_VERIFY_V2: TGUID = '{00AAC56B-CD44-11d0-8CC2-00C04FC295EE}'; WTD_CHOICE_FILE = 1; WTD_REVOKE_NONE = 0; WTD_UI_NONE = 2; type PWinTrustFileInfo = ^TWinTrustFileInfo; TWinTrustFileInfo = record cbStruct: DWORD; // = sizeof(WINTRUST_FILE_INFO) pcwszFilePath: PWideChar; // required,file name to be verified hFile: THandle; // optional,open handle to pcwszFilePath pgKNownSubject: PGUID; // optional: fill if the subject type is kNown end; PWinTrustData = ^TWinTrustData; TWinTrustData = record cbStruct: DWORD; pPolicyCallBACkData: Pointer; pSIPClientData: Pointer; dwUIChoice: DWORD; fdwRevocationchecks: DWORD; dwUnionChoice: DWORD; pFile: PWinTrustFileInfo; dwStateAction: DWORD; hWVTStateData: THandle; pwszURLReference: PWideChar; dwProvFlags: DWORD; dwUIContext: DWORD; end; function WinVerifyTrust(hwnd: HWND; const ActionID: TGUID; ActionData: Pointer): Longint; stdcall; external wintrust; {-----------------------------------------------} function IsCodeSigned(const Filename: String): Boolean; var file_info: TWinTrustFileInfo; trust_data: TWinTrustData; begin // Verify that the exe is signed and the checksum matches FillChar(file_info,SizeOf(file_info),0); file_info.cbStruct := sizeof(file_info); file_info.pcwszFilePath := PWideChar(WideString(FileName)); FillChar(trust_data,SizeOf(trust_data),0); trust_data.cbStruct := sizeof(trust_data); trust_data.dwUIChoice := WTD_UI_NONE; trust_data.fdwRevocationchecks := WTD_REVOKE_NONE; trust_data.dwUnionChoice := WTD_CHOICE_FILE; trust_data.pFile := @file_info; Result := WinVerifyTrust(INVALID_HANDLE_VALUE,WINTRUST_ACTION_GENERIC_VERIFY_V2,@trust_data) = ERROR_succesS end; {-----------------------------------------------} function IsCompanySigningCertificate(const Filename,CompanyName :string): Boolean; var hExe: HMODULE; Cert: PWinCertificate; CertContext: PCCERT_COntexT; CertCount: DWORD; CertName: AnsiString; CertNameLen: DWORD; VerifyParams: CRYPT_VERIFY_messaGE_PARA; begin // Returns TRUE if the SubjectName on the certificate used to sign the exe is // "Company Name". Should prevent a cracker from modifying the file and // re-signing it with their own certificate. // // Microsoft has an example that does this using CryptQueryObject and // CertFindCertificateInStore instead of CryptVerifymessageSignature,but // CryptQueryObject is NT-only. Using CertCreateCertificateContext doesn't work // either,though I don't kNow why. Result := false; // Verify that the exe was signed by our private key hExe := CreateFile(PChar(FileName),GENERIC_READ,FILE_SHARE_READ,nil,OPEN_EXISTinG,FILE_ATTRIBUTE_NORMAL or FILE_FLAG_RANDOM_ACCESS,0); if hExe = INVALID_HANDLE_VALUE then Exit; try // There should only be one certificate associated with the exe if (not ImageEnumerateCertificates(hExe,CERT_SECTION_TYPE_ANY,CertCount,0)) or (CertCount <> 1) then Exit; // Read the certificate header so we can get the size needed for the full cert GetMem(Cert,SizeOf(TWinCertificatE) + 3); // ImageGetCertificateHeader writes an DWORD at bCertificate for some reason try Cert.dwLength := 0; Cert.wRevision := WIN_CERT_REVISION_1_0; if not ImageGetCertificateHeader(hExe,Cert^) then Exit; // Read the full certificate ReallOCMem(Cert,SizeOf(TWinCertificatE) + Cert.dwLength); if not ImageGetCertificateData(hExe,Cert,Cert.dwLength) then Exit; // Get the certificate context. CryptVerifymessageSignature has the // side effect of creaTing a context for the signing certificate. FillChar(VerifyParams,SizeOf(VerifyParams),0); VerifyParams.cbSize := SizeOf(VerifyParams); VerifyParams.dwMsgAndCertEncodingType := X509_ASN_ENCODING or PKCS_7_ASN_ENCODING; if not CryptVerifymessageSignature(VerifyParams,@Cert.bCertificate,Cert.dwLength,@CertContext) then Exit; try // Extract and compare the certificate's subject names. Don't // compare the entire certificate or the public key as those will // change when the certificate is renewed. CertNameLen := CertGetNameStringA(CertContext,CERt_name_SIMPLE_DISPLAY_TYPE,0); SetLength(CertName,CertNameLen - 1); CertGetNameStringA(CertContext,PAnsiChar(CertName),CertNameLen); if CertName <> CompanyName then Exit; finally CertFreeCertificateContext(CertContext) end; finally FreeMem(Cert); end; finally CloseHandle(hExE); end; Result := True; end;
以上是大佬教程为你收集整理的windows – 从Delphi中以编程方式检查数字签名全部内容,希望文章能够帮你解决windows – 从Delphi中以编程方式检查数字签名所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。