Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 4620586
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 22, 20262026-05-22T02:34:51+00:00 2026-05-22T02:34:51+00:00

I need a function in Delphi to verify the digital signature of an external

  • 0

I need a function in Delphi to verify the digital signature of an external EXE or DLL. In my particular application, I am going to occasionally invoke other processes, but for security purposes I want to make sure these executables were created by our organization before running them.

I have seen Microsoft’s example in C, however, I do not want to waste the time translating this to Delphi if somebody else already has.

I would prefer a snippet or code example over a third-party library. Thanks.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-22T02:34:51+00:00Added an answer on May 22, 2026 at 2:34 am

    Here you go:

    // 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, nil, 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, 0, Cert^) then
            Exit;
          // Read the full certificate
          ReallocMem(Cert, SizeOf(TWinCertificate) + Cert.dwLength);
          if not ImageGetCertificateData(hExe, 0, 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, 0, @Cert.bCertificate,
             Cert.dwLength, nil, nil, @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, nil, nil, 0);
            SetLength(CertName, CertNameLen - 1);
            CertGetNameStringA(CertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0,
              nil, PAnsiChar(CertName), CertNameLen);
            if CertName <> CompanyName then 
              Exit;
          finally
            CertFreeCertificateContext(CertContext)
          end;
        finally
          FreeMem(Cert);
        end;
      finally
        CloseHandle(hExe);
      end;
      Result := True;
    end;
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have created bandwidth monitoring function in delphi dll, where i need to raise
I need to call RtlQueryProcessHeapInformation in Delphi. RtlQueryProcessHeapInformation is a function exported from ntdll.dll.
I need following function (from C++ dll) available in C++/CLI extern C _declspec(dllexport) void
I need a function with the following signature: System.Reflection.PropertyInfo getPropertyInfo(System.Type type, string NavigationPath) or
Using Delphi, I need a function to evaluate the current date and see if
I'm trying to call an external Delphi function from C# which takes a Delphi
I'm using Delphi 2007. I need write a FormatDateTime function that always return 01/01/
Possible Duplicate: Standard URL encode function? I need to transofrm a Delphi string (like
I've inherited a Delphi application which I need to convert to a C# application
I need to use a DLL (Hardware ID Extractor) made in Delphi 7 in

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.