It is possible to call all the functions in our cryptographic products CryptoSys API, CryptoSys PKI, FirmaSAT and SC14N from Delphi and Free Pascal. This page explains what we know and gives some sample code.
Summary | Changes since 2010 | CryptoSys API | CryptoSys PKI | FirmaSAT | SC14N | Notes for programmers | Compiling | Acknowledgements | Disclaimer | Contact
2023-11-01:
Added interface for CryptoSys PKI (code dated 2023-10-12)
2023-04-14:
Added interface for SC14N.
2023-04-14: All the code on this page has been re-tested as of April 2023. It all compiles for us using the Free Pascal Compiler version 3.2.2 for i386 in Delphi compatibility mode. YMMV. Please read the Disclaimer below.
2021-01-16: Added recommendations on pointers by Christian Aymon [**].
If it works for you, please use it. If you have any corrections or useful suggestions, we'd be delighted to hear from you. Please send us a message.
The code and links on this page are all the Delphi code we have. For more info on creating interfaces see Writing an interface in another programming language.
The test code samples give a small set of tests to demonstrate representative functions for each interface. You should be able to figure out how to use the other functions from the examples given.
CryptoSys API | CryptoSys PKI | FirmaSAT | SC14N | |
---|---|---|---|---|
Unit | diCryptoSys.pas | diCrPKI.pas | diFirmaSat.pas | diSc14n.pas |
Tests | TestCrSysAPI.pas | TestCrSysPKI.pas | TestFirmaSat.pas | TestSc14n.pas |
Download | zip | zip | zip | zip |
Last updated | 2016-01-27 | 2023-10-12 | 2016-01-27 | 2023-04-14 |
Doesn't compile for you? See compiling.
2016-01-27: Changes since we first published the Delphi interface in 2010.
{$Include diCryptoSys}
to uses diCryptoSys;
.
Integer
to LongInt
to ensure the proper 32-bit size integers are used.
{$mode Delphi}
to the test code so we can test using Free Pascal._UpdateHex
functions which operate in situ on a String
type.
Here is a Delphi/FreePascal interface to all the functions in CryptoSys API with some representative tests: diCryptoSys.pas.zip. The function declarations and associated constants are in the file diCryptoSys.pas. Please read the Disclaimer below.
For more information on the CryptoSys API function parameters and return values, see the C include file diCryptoSys.h and the Main manual.
You need to have installed CryptoSys API on your system. See the CryptoSys API home page.
Another example:
This sample code shows how to use the functions
CIPHER_EncryptBytesPad
and
CIPHER_DecryptBytesPad
using Aes128/CBC/pkcs5
,
along with some utilities for converting between arrays of bytes, hex-encoded strings and AnsiStrings.
Note that this particular code will also work in CryptoSys PKI Pro if you replace
uses SysUtils, diCryptoSys;
by uses SysUtils, diCrPKI;
.
New v22.0:
Here is a Delphi/FreePascal interface to all the functions in CryptoSys PKI with some representative tests:
diCrPKI.pas.zip.
The function declarations and associated constants are in the file diCrPKI.pas.
Please read the Disclaimer below.
For more information on the CryptoSys PKI function parameters and return values, see the C include file diCrPKI.h and the Main manual.
You need to have installed CryptoSys PKI on your system. See the CryptoSys PKI home page.
Pedro Miguel Martins has provided some code in Delphi that uses the Delphi interface to CryptoSys PKI to compute an RSA signature using the test key for the Portugal General Directorate of Taxes (Direcção Geral dos Impostos). See Portugal DGCI Delphi Code.
Here is a Delphi/FreePascal interface to all the functions in FirmaSAT with some representative tests: diFirmaSat.pas.zip. The function declarations and associated constants are in the file diFirmaSat.pas. Please read the Disclaimer below.
For more information on the FirmaSAT function parameters and return values, see the C include file diFirmaSat2.h and the manual.
You need to have installed FirmaSAT on your system. For more information see the FirmaSAT home page.
Note that the tests in TestFirmaSat require certain files to exist in a specified directory. The test files are provided in the zip file above. The directory is hardcoded in the code.
const
TEST_DIR = 'C:\Test\Muestra';
- please edit this to suit your system.
Note also that these test files are now old (2016), but the Pascal functions are still compatible with the latest versions of FirmaSAT.
Here is a Delphi/FreePascal interface to all the functions in SC14N with some representative tests. The function declarations and associated constants are in the file diSc14n.pas and the tests are in TestSc14n.pas.
These are included in diSc14n.pas.zip along with a test XML file. Please read the Disclaimer below.
For more information on the SC14N function parameters and return values, see the C include file diSc14n.h and the Documentation.
Note that all strings used in this Delphi interface are single-byte AnsiString
. To pass UTF-8 XML data in a string,
you must encode any Wide or Unicode string to UTF-8 bytes in an AnsiString.
You need to have installed SC14N on your system. See the SC14N home page.
Variable types used in the interface:
C++ Type | VBA Type | Delphi Type | Description |
---|---|---|---|
long, int | Long | LongInt | A signed 32-bit integer, passed by value |
const char *sz | String | AnsiString | ANSI string: a string of single-byte non-zero characters terminated by a zero byte |
unsigned char *lp | Byte | Array of Byte | Byte array: an ordered sequence of single-byte values of any value in the range [0,255] |
LongInt
, a 32-bit signed integer.AnsiString
.
Attempting to pass a "default" Unicode or Wide String
will not work.Array of Byte
.function FOO_StringFunction(szOutput : PAnsiChar; nMaxChars : LongInt; szData : AnsiString) : LongInt; function FOO_ByteFunction(lpOutput : PByte; nOutBytes : LongInt; lpInput : PByte; nInputLen : LongInt) : LongInt;
strbuf : AnsiString; //... strbuf := AnsiString(StringOfChar(#0, nchars)); ret := FOO_StringFunction(Pointer(strbuf), nchars, ...); // See [**/2] below ret := FOO_StringFunction(PAnsiChar(strbuf), nchars, ...);
arrbytes : Array of Byte; //... SetLength(arrbytes, nbytes); ret := FOO_ByteFunction(Pointer(arrbytes), nbytes, ...); // OR - See [**/3] below. ret := FOO_ByteFunction(Addr(arrbytes[0]), nbytes, ...);These output parameters are expected as
PAnsiChar
and PByte
respectively.
AnsiString
type.
Constant byte arrays passed as input still need to be passed as a pointer.
szData : AnsiString;
//...
ret := FOO_StringFunction(PAnsiChar(strbuf), nchars, szData);
lpData : Array of Byte;
//...
ret := FOO_ByteFunction(Pointer(arrbytes), nbytes, Pointer(lpData), Length(lpData));
In fact, you can pass a pointer to an AnsiString
as an argument to a function expecting a byte array as input.
S : AnsiString;
//...
S = 'abc';
ret := FOO_ByteFunction(Pointer(arrbytes), nbytes, Pointer(S), Length(S));
AnsiString
or Array of Byte
, use the Delphi NIL
value, as in
nchars := SAT_CompileTime(NIL, 0);
abKey : Array of Byte; tag : Array[0..15] of Byte; //... ret := GCM_Encrypt(NIL, 0, @tag[0], Length(tag), NIL, 0, Pointer(abKey), Length(abKey),...);
Update: [**/4] - You can use Addr(x[0])
in both cases.
SetLength
operation
SetLength(abOut, Length(abIn));
_UpdateHex
functions which update a string parameter in situ don't work properly in Delphi/Pascal, so don't use them.
strbuf := AnsiString(StringOfChar(#0, nchars));where
nchars
is the maximum number of characters you require in the string.
The above code will automatically add the extra character to the storage for the null byte, which will be added automatically by the DLL.
This is equivalent to the VBA code used in the manual
strbuf = String(nchars, " ")
BUT if instead you use
SetLength(strbuf, nchars);the buffer will be too short by one and will (eventually, maybe, sometimes) cause a GPF error (you should have used
nchars+1
).
However, using SetLength
for a byte array is OK, though
- I would avoid the
Pointer(x)
construction.- I would use
PAnsiChar(strbuf)
instead ofPointer(strbuf)
.- Instead of
Pointer(arrbytes)
I would useAddr(arrbytes[0])
.- You can use
Addr(x[0])
in both cases.
We compiled and ran all these examples using FPC version 3.2.2 on the command line. All the interface unit files were in the current working directory.
>fpc TestCrSysAPI.pas Free Pascal Compiler version 3.2.2 [2021/05/15] for i386 Copyright (c) 1993-2021 by Florian Klaempfl and others Target OS: Win32 for i386 Compiling TestCrSysAPI.pas Linking TestCrSysAPI.exe 537 lines compiled, 0.2 sec, 89760 bytes code, 4756 bytes data >TestCrSysAPI Running testcrsysapi.exe at 14/04/2023 19:08:33 GENERAL: Interrogate the core diCryptoSys DLL: API_Version=62000 ...
If you run the tests in an IDE you may need to add a ReadLn
statement to the main procedure.
Thanks to Sebastian Jäschke and Humberto Souza for their help in providing example Delphi interfaces to CryptoSys API, without which we would not have been able to get started, and to Cesar Ruiz for his feedback, and Dr Richard Koch and Christian Aymon. Thanks, too, to Neil Moffatt for his excellent Delphi Basics site.
We do not offer to support or maintain any code on this page or provide any updates to reflect changes in the underlying CryptoSys libraries. We just provide this sample code as is. We will try and help if we can (if you ask nicely). Use at your own risk with no warranties. The code on this page is offered for free in good faith but may contain traces of nuts and/or errors. Before purchasing any of our products, please carry out whatever checks with the free Trial Edition to satisfy yourself it does what you require.
For more information or to comment on this page, please send us a message.
This page first published 13 March 2010. Last updated 1 November 2023.