Sample code for 30+ languages & platforms
Pascal (Lazarus/Delphi)

A3/A4 Certificate to Create and Verify an Opaque PKCS7/CMS Signature

See more Digital Signatures Examples

Demonstrates how to use an A3 or A4 certificate w/ private key on a smartcard or token to create a PKCS7 opaque signature, and also how to verify an opaque signature.

An opaque signature is different than a detached PKCS7 signature in that it contains the original data. Verifying an opaque signature retrieves the original content.

Chilkat Pascal (Lazarus/Delphi) Downloads

Pascal (Lazarus/Delphi)
program ChilkatDemo;

// Demonstrates using the Chilkat Pascal wrapper via the C bridge DLL.
// Builds as a console application under Lazarus (FPC) or Delphi.

{$IFDEF FPC}
  {$MODE DELPHI}
{$ENDIF}
{$APPTYPE CONSOLE}

uses
  {$IFDEF UNIX}
  cthreads,
  {$ENDIF}
  SysUtils,
  CkDllLoader,
  Chilkat.Cert,
  Chilkat.Crypt2;

// ---------------------------------------------------------------------------

procedure RunDemo;
var
  success: Boolean;
  crypt: TCrypt2;
  cert: TCert;
  originalData: string;
  opaqueSig: string;
  vCrypt: TCrypt2;
  extractedData: string;

begin
  success := False;

  //  This example assumes the Chilkat API to have been previously unlocked.
  //  See Global Unlock Sample for sample code.

  crypt := TCrypt2.Create;

  //  A certificate and private key is needed to create a signature.
  //  Chilkat provides many different ways to load a certificate and private key, such
  //  as from a smartcards and hardware tokens, PFX/.p12, Java keystore, JWK, Windows registry-based certificate stores, and other sources.
  //  This example will load the default certificate from the smartcard that is currently in
  //  the smartcard reader.

  cert := TCert.Create;

  //  If the smartcard or token requires a PIN, we can set it here to avoid the dialog...
  cert.SmartCardPin := '000000';

  success := cert.LoadFromSmartcard('');
  if (success <> True) then
    begin
      WriteLn(cert.LastErrorText);
      Exit;
    end;

  //  Tell it to use the cert and private key we've loaded.
  success := crypt.SetSigningCert(cert);
  if (success <> True) then
    begin
      WriteLn(crypt.LastErrorText);
      Exit;
    end;

  //  Indicate we want the opaque signature in base64 format:
  crypt.EncodingMode := 'base64';

  //  Sign the string using the "utf-8" byte representation:
  crypt.Charset := 'utf-8';

  //  Create the opaque signature:
  originalData := 'This is the string to be signed.';
  opaqueSig := crypt.OpaqueSignStringENC(originalData);
  if (crypt.LastMethodSuccess <> True) then
    begin
      WriteLn(crypt.LastErrorText);
      Exit;
    end;

  WriteLn(opaqueSig);

  //  The output looks like this:
  //  MIIPgQYJKoZIhvcNAQcCoIIPcjCCD24CAQExCzAJBgUrDgMCGgUAMC8GCSqGSIb3DQEHAaAiBCBUaGlzIGlzIHRoZSBzdHJpbmcgdG8gYmUgc...

  //  ----------------------------------------------------------------------------------------------
  //  Now let's verify the signature and retrieve the original data.
  //  We'll use a new Crypt2 object to keep things completely separate...

  vCrypt := TCrypt2.Create;

  //  We only need the certificate to verify a signature (and extract the data from
  //  an opaque signature).  The public key is always embedded within a certificate.
  success := vCrypt.SetVerifyCert(cert);
  if (success <> True) then
    begin
      WriteLn(vCrypt.LastErrorText);
      Exit;
    end;

  vCrypt.EncodingMode := 'base64';
  vCrypt.Charset := 'utf-8';

  extractedData := vCrypt.OpaqueVerifyStringENC(opaqueSig);
  if (vCrypt.LastMethodSuccess <> True) then
    begin
      WriteLn(vCrypt.LastErrorText);
      Exit;
    end;

  WriteLn('The extracted data: ' + extractedData);

  //  The output is:
  //  The extracted data: This is the string to be signed.


  crypt.Free;
  cert.Free;
  vCrypt.Free;

end;

// ---------------------------------------------------------------------------

begin

  try
    RunDemo;
  except
    on E: Exception do
      WriteLn('Unhandled exception: ', E.ClassName, ': ', E.Message);
  end;

  WriteLn;
  {$IFDEF MSWINDOWS}
  WriteLn('Press Enter to exit...');
  ReadLn;
  {$ENDIF}
end.