Rivest-Shamir-Adleman (RSA) Public-Key Cryptography
The RSA public-key algorithm was designed back in 1977, and is still the most widely used. In order to fully implement it, we need to generate new key pairs (public and private keys), then sign and verify (or encrypt or decrypt) data with the key. For instance, a private key is kept secret, and used for an Authority to sign a certificate, and the public key is published, and able to verify a certificate. It is based on large prime numbers, so we needed to develop a Big Integer library, which is not part of Delphi or FPC RTL.
Here as some notes about our implementation in mormot.crypt.rsa.pas:
- new pure pascal OOP design of BigInt computation optimized for RSA process;
- dedicated x86_64/i386 asm for core computation routines (noticeable speedup);
- use half-registers (HalfUInt) for efficient computation on all CPUs (arm and aarch64 numbers are good);
- slower than OpenSSL, but likely to be the fastest FPC or Delphi native RSA library, thanks to our optimized asm: for instance, you can generate a new RSA-2048 keypair in less than a second;
- internal garbage collection of BigInt instances, to minimize heap pressure during computation, and ensure all values are wiped once used during the process - as proven anti-forensic measure;
- includes FIPS-level RSA keypair validation and generation, using a safe random source, with efficient prime number detection, and minimal code size;
- features both RSASSA-PKCS1-v1_5 and RSASSA-PSS signature schemes;
- started as a fcl-hash fork, but full rewrite inspired by Mbed TLS source because this initial code is slow and incomplete;
- references: we followed the Mbded TLS implementation (which is much easier to follow than OpenSSL), and the well known Handbook of Applied Cryptography (HAC) recommendations;
- includes full coverage of unit tests to avoid any regression, validated against the OpenSSL library as audited reference;
- this unit will register as
Asym'RS256','RS384','RS512' algorithms (if not overridden by the faster
mormot.crypt.openssl), keeping 'RS256-int' and 'PS256-int' available to use our unit;
- as used by
mormot.crypt.x509(see below) to handle RSA signatures of its X.509 Certificates.
For instance, if you want to access a
TCryptAsym digital signature instance with RSA-2048 and SHA-256 hashing, you can just use the
CryptAsym global variable with
caaRS256 algorithm as factory.
If you need just public/private key support, you can use
CryptPrivateKey factories with
About RSA security:
- RSA-512 or RSA-1024 are considered unsafe and should not be used.
- RSA-2048 confers 112-bit of security, and is the usual choice today when this algorithm is to be used.
- RSA-3072 could confer 128-bit of security, at the expense of being slower and 50% bigger - so switching to ECC-256 may be a better option, for the same level of security.
- RSA-4096 is not worth it in respect to RSA-3072, and RSA-7680 is very big and slow, and only gives 192-bit of security, so should be avoided.
Anyway, our library is able to support all those key sizes, up to RSA-7680 is you really need it.
See this SO response as reference about RSA keysizes.
As we wrote in introduction, X.509 certificates are the base of most computer security.
The whole TLS/HTTPS stack makes use of it, and the whole Internet would collapse without it.
We developed our mormot.crypt.x509.pas unit from scratch, featuring:
- X.509 Certificates Fields Logic (e.g. X.501 Type Names);
- X.509 Certificates and Certificate Signing Request (CSR);
- X509 Certificate Revocation List (CRL);
- X509 Private Key Infrastructure (PKI);
- Registration of our X.509 Engine to the
The raw binary encoding is using the (weird) ASN.1 syntax, which is now implemented as part of the mormot.crypt.secure.pas unit.
We followed the RFC 5280 specifications, and mapped latest X.509 Certificates / CSR / CRL extensions, with some low-level but very readable pascal code using classes, records and enumerates. It features perfect compatibility with our
ICryptCert high-level interface wrappers, ready to be used in a very convenient way. We support all basic functions, but also advanced features like open/sealing or text peer information in a human readable format.
When using our unit, your end-user code should not be lost within the complex details and notions of the X.509 format (like OIDs, versions or extensions), but use high-level pascal code, with no possibility to use a weak or invalid configuration.
Of course, it can support not only our new RSA keys, but also ECC-256 as implemented by our native mormot.crypt.ecc.pas, or any other algorithm, e.g. available from OpenSSL.
X.509 Private Key Infrastructure (PKI)
Our unit features a full Private Key Infrastructure (PKI) implementation.
In fact, X.509 certificates are as weak as the PKI they are used on. You can have strong certificates, but a weak verification pattern. In end-user applications, it is typical to see all the security being lost by a poor (e.g. naive) implementation of the keys interaction.
This is why our unit publishes a 'x509-pki'
ICryptStore as a full featured PKI:
- using our
TX509Crlclasses for actual certificates process;
- clean verification of the chain of trust, with customized depth and proper root Certificate Authority (CA) support, following the RFC 5280 section 6 requirements of a clean "Certification Path Validation";
- maintaining a cache of
ICryptCertinstances, which makes a huge performance benefit in the context of a PKI (e.g. you don't need to parse the X.509 binary, or verify the chain of trust each time).
We tried to make performance and usability in the highest possible standards, to let you focus on your business logic, and keep the hard cryptography work done in the mORMot library code.
Hardware Security Modules (HSM) via PKCS#11
The PKCS#11 standard is a way to define some software access to Hardware Security Modules, via a set of defined API calls.
We just published the mormot.crypt.pkcs11.pas unit to interface those devices with the other mORMot PKI.
Once you have loaded the library of your actual hardware (typically a
.so) using a
TCryptCertAlgoPkcs11 instance, you can see all stored certificates and keys, as high-level regular
ICryptCert instances, and sign or verify any kind of data (some binary or some other certificates), using the private key safely stored on in the hardware device.
This is usually slower than a pure software verification, but it is much safer, because the private key is sealed within the hardware token, and never leave it. So it can't be intercepted and stolen.
You are Welcome!
With those mORMot cryptography units, you now have anything at hand to use standard and proven public-key cryptography in your applications, on both Delphi or FPC, with no external dll deployment issue, and minimal code size increase.
We can thank a lot my employer for needing those nice features, therefore letting me work on them.
Open Source rocks! :)