How to Sign a String Using Ipworks TipcRSA in Delphi

Sign a String Using Ipworks TipcRSA

In this post, I will walk you through a Delphi unit test that demonstrates how to sign a string using the TipcRSA component from the Ipworks library. The focus here is on using the RSA signing algorithm with SHA256 hashing and encoding the signature in Base64 format. This is particularly useful for scenarios like generating signatures for SAML assertions or any other cryptographic operations requiring RSA.

The code I’m sharing will be useful for developers working with cryptographic operations in Delphi, specifically when using Ipworks. The following method will show how to perform these tasks.

Prerequisites

Before diving into the implementation, ensure that you have the ipcRSA unit from Ipworks added to your project. The TipcRSA class is part of this unit, and it is essential for the RSA signing functionality.

The Delphi Code

Here’s the implementation for the test case:

 

 
procedure SAMLTests.TestANSI;
var
  vRSA: TipcRSA;
  vSignature: string;
  vBytes: TBytes;
  vBase64Encoder: TBase64Encoding;

  // Helper function to convert a Hex string to Bytes
  function HexToBytes(const HexStr: string): TBytes;
  var
    i: Integer;
  begin
    SetLength(Result, Length(HexStr) div 2);
    for i := 0 to Length(Result) - 1 do
    begin
      Result[i] := StrToInt('$' + Copy(HexStr, (i * 2) + 1, 2));
    end;
  end;

begin
  // Initialize the RSA object
  vRSA := TipcRSA.Create(nil);
  try
    // Load the private key from a PEM-formatted file
    vRSA.CertEncoded := TFile.ReadAllText('path to private key in PEM format');
    
    // Set the RSA hash algorithm to SHA256
    vRSA.HashAlgorithm := rhaSHA256;

    // Assign the input message to be signed
    vRSA.InputMessage := FToSign;
    
    // Set the signature output format to Hex
    vRSA.UseHex := true;

    // Sign the message
    vRSA.Sign;

    // Convert the Hex signature to Bytes
    vBytes := HexToBytes(vRSA.HashSignature);

    // Initialize Base64 encoder
    vBase64Encoder := TBase64Encoding.Create(0);
    try
      // Convert the bytes to a Base64 encoded string
      vSignature := vBase64Encoder.EncodeBytesToString(vBytes);
    finally
      // Free the Base64 encoder
      vBase64Encoder.Free;
    end;

    // Output the results
    writeln('TEncoding.ANSI.GetBytes');
    LogResults(vSignature);
  finally
    // Clean up RSA object
    vRSA.Free;
  end;

  // Assert to ensure the generated signature matches the expected one
  Assert.AreEqual(FCorrectSignature, vSignature);
end;

Breakdown of the Code

  1. RSA Initialization:
    • The TipcRSA object (vRSA) is instantiated, and the private key is loaded from a PEM file using the CertEncoded property. This private key is crucial for signing the string.
  2. Hashing and Signing:
    • The HashAlgorithm is set to SHA256, a secure hashing algorithm.
    • The InputMessage is assigned the string you want to sign.
    • The Sign method is called, which creates the RSA signature in hexadecimal format.
  3. Hex to Bytes Conversion:
    • A helper function HexToBytes is used to convert the hexadecimal signature to a byte array. This step is necessary to prepare the signature for Base64 encoding.
  4. Base64 Encoding:
    • A TBase64Encoding object is used to convert the byte array into a Base64 encoded string, which is the final format for the signature.
  5. Assertion:
    • An assertion is made to compare the generated signature (vSignature) with the expected signature (FCorrectSignature).

Importance of the ipcRSA Unit

The ipcRSA unit is essential because it contains the TipcRSA class, which handles the RSA signing operations. Without this unit, you won’t be able to access the TipcRSA component, which is necessary for cryptographic signing in Delphi. Make sure this unit is properly referenced in your project.

Conclusion

In this tutorial, you’ve learned how to implement RSA signing using the TipcRSA component from Ipworks in Delphi. The key steps involve loading the private key, setting up the signing algorithm, and converting the signed output into Base64. This approach can be adapted for various cryptographic tasks in your applications.