EldoS | Feel safer!

Software components for data protection, secure storage and transfer

Signing a string using a certificate from the store (Delphi 7)

Also by EldoS: CallbackProcess
A component to control process creation and termination in Windows and .NET applications.
#30239
Posted: 08/08/2014 06:27:49
by ROWEL LIRAG (Standard support level)
Joined: 08/08/2014
Posts: 11

I am using an evaluation version of SecureBlackBox.
I need a sample in Delphi 7 on how to sign a string(just text) using a user's selected certificate from the 'MY' certificate store.
Thank you.
#30240
Posted: 08/08/2014 06:34:33
by Vsevolod Ievgiienko (EldoS Corp.)

Thank you for contacting us.

We don't have a ready-to-use sample for such case, but you can look into a few of our samples for details and combine them to achieve the result:

1) \EldoS\SecureBlackbox.VCL\Samples\Delphi\PKIBlackbox\Certificates - shows how to load certificates from Windows stores;
2) \EldoS\SecureBlackbox.VCL\Samples\Delphi\PKIBlackbox\Primitives\SignDetached - shows how to create PKCS#1 signature.
3) \EldoS\SecureBlackbox.VCL\Samples\Delphi\PKIBlackbox\PKCS7 - shows how to perform PKCS#7 signing with a certificate.
#30241
Posted: 08/08/2014 06:36:35
by Vsevolod Ievgiienko (EldoS Corp.)

Note that cryptographic algorithms doesn't deal with strings, but with raw bytes. So you should simply convert a string to a byte array before signing (e.g. using UTF-8 encoding).
#30273
Posted: 08/12/2014 07:54:45
by ROWEL LIRAG (Standard support level)
Joined: 08/08/2014
Posts: 11

In C# I have the following method to sign a blob with the certificate's private key and verify the signature using the certificate's public key.

I managed with the help of your samples to get the Delphi 7 equivalent of signing... how do I go about verifying that the signature is correct using the certificate's public key?

Note: Delphi 7 code follows the C# code below.

Code
static void SignABlob(X509Certificate2 certificate, string blob)
{
   RSACryptoServiceProvider privateKey = certificate.PrivateKey as RSACryptoServiceProvider;
   byte[] buffer = Encoding.Default.GetBytes(blob);
   byte[] signature = privateKey.SignData(buffer, new SHA1Managed());
   Console.WriteLine("Signature input: " + blob);
   Console.WriteLine("Signed Hash: " + Encoding.Default.GetString(signature));

   RSACryptoServiceProvider publicKey = certificate.PublicKey.Key as RSACryptoServiceProvider;
   bool verify = publicKey.VerifyData(buffer, new SHA1Managed(), signature);
   Console.WriteLine("Verified? " + verify.ToString());
   Console.ReadLine();
}


Delphi 7 Code...
Code
procedure TfrmMainForm.Sign;
var
  Crypto: TElPublicKeyCrypto;
  StreamInput, StreamSignature: TMemoryStream;
  Cert: TElX509Certificate;
  S: TBytes;
  VR: TSBPublicKeyVerificationResult;
  aStreamSignature: String;

  function UTF8Bytes(const s: UTF8String): TBytes;
  begin
    SetLength(Result, Length(s));
    if Length(Result)>0 then
      Move(s[1], Result[0], Length(s));
  end;

begin
  Crypto := TElRSAPublicKeyCrypto.Create();
  Cert := WinCertStorage.Certificates[cmbWindowsCertificates.ItemIndex - 1];

  S := UTF8Bytes('blob');

  try
    Crypto.InputEncoding      := pkeBinary;
    Crypto.OutputEncoding     := pkeBinary;
    Crypto.KeyMaterial        := Cert.KeyMaterial;
    Crypto.InputIsHash        := False; //True;
    Crypto.HashAlgorithm      := SB_ALGORITHM_DGST_SHA1;

    StreamInput := TMemoryStream.Create;
    StreamInput.Write(S[1], Length(S));
    StreamInput.Position := 0;

    StreamSignature := TMemoryStream.Create;

    try
      Crypto.SignDetached(StreamInput, StreamSignature);

      SetLength(S, StreamSignature.Size);
      StreamSignature.Position := 0;
      StreamSignature.Read(S[1], StreamSignature.Size);

    except
      on E : Exception do
          ShowMessage(E.ClassName+' error raised, with message : '+E.Message)
    end;
    finally
      FreeAndNil(StreamInput);
      FreeAndNil(StreamSignature);
      FreeAndNil(Crypto);
    end;
end;

Thank you...
#30275
Posted: 08/12/2014 08:05:39
by Vsevolod Ievgiienko (EldoS Corp.)

\EldoS\SecureBlackbox.VCL\Samples\Delphi\PKIBlackbox\Primitives\VerifyDetached sample shows how to verify the signature.
#30304
Posted: 08/13/2014 12:56:13
by ROWEL LIRAG (Standard support level)
Joined: 08/08/2014
Posts: 11

I am using the evaluation version of SecureBlackBox.

My question:
I need to validate a signature using a selected certficate.

Why am I being asked for the location of SBCryptoProvBuiltInPKI.pas at the line Crypto.VerifyDetached? The certificate comes from the WinCertStorage (TElWinCertStorage).


Code
function TfrmMainForm.ValidateSignature(Cert: TElX509Certificate; Signature: string): boolean;
var
  Crypto: TElPublicKeyCrypto;
  StreamInput, StreamOutput: TMemoryStream;
  blob: TBytes;
  VR: TSBPublicKeyVerificationResult;

begin
  Crypto := TElRSAPublicKeyCrypto.Create();
  blob := GetBytes(Signature);

  try
    Crypto.InputEncoding      := pkeBinary;
    Crypto.OutputEncoding     := pkeBase64;
    Crypto.KeyMaterial        := Cert.KeyMaterial;

    StreamInput := TMemoryStream.Create;
    StreamInput.Write(blob[1], Length(blob));
    StreamInput.Position := 0;

    StreamOutput := TMemoryStream.Create;

      try
        Crypto.VerifyDetached(StreamInput, StreamOutput);
        case VR of
          pkvrSuccess :
            MessageDlg('Verification succeeded', mtInformation, [mbOk], 0);
          pkvrFailure :
            MessageDlg('Verification failed', mtError, [mbOk], 0);
          pkvrInvalidSignature :
            MessageDlg('Invalid signature', mtError, [mbOk], 0);
          pkvrKeyNotFound :
            MessageDlg('Validation key not found', mtError, [mbOk], 0);
        end;
      except
        on E : Exception do
            ShowMessage(E.ClassName+' error raised, with message : '+E.Message)
      end;

    finally
      FreeAndNil(StreamInput);
      FreeAndNil(StreamOutput);
      FreeAndNil(Crypto);
    end;
end;
#30305
Posted: 08/13/2014 13:09:17
by Eugene Mayevski (EldoS Corp.)

Quote
ROWEL LIRAG wrote:
Why am I being asked for the location of SBCryptoProvBuiltInPKI.pas at the line Crypto.VerifyDetached?


You are running the code under IDE and if the exception happens, the IDE attempts to find and load the source file where the exception happens. If you ignore the prompt, execution will continue and the exception will be either shown or passed to the application.


Sincerely yours
Eugene Mayevski
#30307
Posted: 08/13/2014 13:30:55
by ROWEL LIRAG (Standard support level)
Joined: 08/08/2014
Posts: 11

I gather as much but for the life of me I can't figure out where I am doing it wrong. Am I passing the wrong parameters to Crypto ?
#30309
Posted: 08/13/2014 13:43:21
by Eugene Mayevski (EldoS Corp.)

We can only guess without seeing the actual exception type and message.

Quote
ROWEL LIRAG wrote:
StreamInput.Write(blob[1], Length(blob));


that's not correct -- IIRC TBytes is 0-based, so you need to pass "blob[0]". Maybe this is the reason of your problem.


Sincerely yours
Eugene Mayevski
#30310
Posted: 08/13/2014 13:58:31
by ROWEL LIRAG (Standard support level)
Joined: 08/08/2014
Posts: 11

Arg! Missed that one, 0-based, ok. fixed that.
I also changed
Crypto.InputEncoding := pkeBinary;
Crypto.OutputEncoding := pkeBinary;
and specified the hash algorithm. same algorithm i used for signing.

When I ran the code, I'm not getting any error messages except for a prompt for the .pas file.

Scratching my head here...

Code

Crypto: TElPublicKeyCrypto;
  StreamInput, StreamOutput: TMemoryStream;
  blob: TBytes;
  VR: TSBPublicKeyVerificationResult;

begin
  Crypto := TElRSAPublicKeyCrypto.Create();
  blob := GetBytes(Signature);

  try
    Crypto.InputEncoding      := pkeBinary;
    Crypto.OutputEncoding     := pkeBinary;
    Crypto.KeyMaterial        := Cert.KeyMaterial;
    Crypto.HashAlgorithm      := SB_ALGORITHM_DGST_SHA1;

    StreamInput := TMemoryStream.Create;
    StreamInput.Write(blob[0], Length(blob));
    StreamInput.Position := 0;

    StreamOutput := TMemoryStream.Create;

      try
        Crypto.VerifyDetached(StreamInput, StreamOutput);
Also by EldoS: Rethync
The cross-platform framework that simplifies synchronizing data between mobile and desktop applications and servers and cloud storages

Reply

Statistics

Topic viewed 4440 times

Number of guests: 1, registered members: 0, in total hidden: 0




|

Back to top

As of July 15, 2016 EldoS Corporation will operate as a division of /n software inc. For more information, please read the announcement.

Got it!