Using OpenSSL 1.1.1 with all Delphi target platforms
Allen Drennan - 04/Aug/2020
Allen Drennan - 04/Aug/2020
[SHOWTOGROUPS=4,20,22]
In this article we are going to discuss how to use the latest version of OpenSsl 1.1.1 with Delphi directly to create X.509 certificates, decode, verify, encode and sign JSON Web Tokens and generate random data. Additionally we will do this in a way that works on Delphi supported platforms including Windows, macOS, iOS, Android and Linux as well as all current compiler targets for 32 and 64-bit devices.
Introduction
The OpenSsl library contains a wealth of useful tools that cover many aspects beyond just encryption and related protocol tasks. OpenSsl is widely used to implement encryption and security over the network and the latest versions of OpenSsl support the newest standard TLS 1.3.
Developers often are reluctant to use OpenSsl in their projects because they must redistribute the library along with their project. Also, it’s nearly impossible to find examples of using it on Delphi platforms other than Windows. The nice thing about using OpenSsl is that the interface for Delphi developers is consistent across all the platforms supported by Delphi. Once you implement it on Windows, you can use that same approach on iOS, Android, Linux and macOS and expect that behavior to be consistent. Additionally, OpenSsl has highly optimized internal crypto routines that typically outperform other crypto libraries on most platforms. This is a consideration when building apps that spend the majority of their time communicating securely over the network or the Internet.
Here at Grijjy we use OpenSsl to implement TLS secure communications over the network when we implement HTTP/S and secure WebSockets. We transmit and receive high-def video, audio and desktop sharing on all the OS platforms supported by Delphi in real-time using WebSockets and TLS with OpenSsl. OpenSsl works well on multi-threaded, scalable socket servers and with bi-directional protocols like WebSockets with TCP or DTLS (datagram TLS) when transmitting data using the UDP protocol. This allows us to have a common network stack to target all the platforms Delphi supports but to do this in a predictable manner.
This is a fundamental issue with using the platform-native (or integrated) approach to HTTP/S and sockets when you need TLS. While you get the advantage of not distributing OpenSsl, it can lead to unpredictable behavior from device to device and from machine to machine for simple tasks such as hashing, HTTP/S and other operations. How one platform-native HTTP/S client handles asynchronous and/or synchronous requests or parallel threads, can vary widely.
Besides the obvious HTTP/S usage, OpenSsl contains a wealth of useful routines that you can use in your Delphi projects. This article will cover just some of those use cases including using OpenSsl to create random bytes, creating your own X.509 certificates and using OpenSsl for handling JSON Web Tokens (JWT). I like simple, straight-forward examples so this is by no means an exhaustive look at these subjects and is only intended as a primer for using OpenSsl with Delphi.
JSON Web Tokens
JSON Web Tokens are very popular as a way to provide the secure exchange of information between applications in the cloud over just exchanging regular access tokens. They are widely used by many services and APIs available in the cloud like those offered by Google.
Traditionally, access tokens are used in OAuth models. While both access tokens and JWTs are used for similar purposes they each have their own characteristics that make them suitable to certain scenarios. With an access token, typically an implementation needs to track the token and lookup whether it has expired or what other detail is related to the token. At Grijjy, we typically cache tokens into memory and a database and then expire them (delete them) when their expiration interval is up. Access tokens require that all the details of the token are maintained until it is no longer needed.
JWTs work a bit differently. A typical JWT contains all the information related to the token within the token itself. This includes enough information validate that the token is authorized and not expired. JWTs can also contain custom payloads specific to your application. For this purposes they can avoid a round trip to a cache of tokens in memory or in the database for each request. However, processing JWTs with each request and validating them can be a time consuming thing. Quite a few APIs end up mixing both access tokens and JWTs for their APIs.
Personally I feel that JWTs can be very efficient, especially if you validate them one time and then cache them into memory until their expiration is up. That way, with each request you are not validating the entire signature of the JWT again but instead just looking up to see if you previously validated the JWT. A full discussion of tokens is beyond the scope of this article, but we will demonstrate JWTs using at least one hash scheme with OpenSsl.
Note: This is not meant as an exhaustive look at JWTs. We are only demonstrating one algorithm. There are other nice libraries for handling JWTs in Delphi. Our intent is to show how OpenSsl can do this in a simple, straightforward and cross-platform way.
[/SHOWTOGROUPS]
In this article we are going to discuss how to use the latest version of OpenSsl 1.1.1 with Delphi directly to create X.509 certificates, decode, verify, encode and sign JSON Web Tokens and generate random data. Additionally we will do this in a way that works on Delphi supported platforms including Windows, macOS, iOS, Android and Linux as well as all current compiler targets for 32 and 64-bit devices.
Introduction
The OpenSsl library contains a wealth of useful tools that cover many aspects beyond just encryption and related protocol tasks. OpenSsl is widely used to implement encryption and security over the network and the latest versions of OpenSsl support the newest standard TLS 1.3.
Developers often are reluctant to use OpenSsl in their projects because they must redistribute the library along with their project. Also, it’s nearly impossible to find examples of using it on Delphi platforms other than Windows. The nice thing about using OpenSsl is that the interface for Delphi developers is consistent across all the platforms supported by Delphi. Once you implement it on Windows, you can use that same approach on iOS, Android, Linux and macOS and expect that behavior to be consistent. Additionally, OpenSsl has highly optimized internal crypto routines that typically outperform other crypto libraries on most platforms. This is a consideration when building apps that spend the majority of their time communicating securely over the network or the Internet.
Here at Grijjy we use OpenSsl to implement TLS secure communications over the network when we implement HTTP/S and secure WebSockets. We transmit and receive high-def video, audio and desktop sharing on all the OS platforms supported by Delphi in real-time using WebSockets and TLS with OpenSsl. OpenSsl works well on multi-threaded, scalable socket servers and with bi-directional protocols like WebSockets with TCP or DTLS (datagram TLS) when transmitting data using the UDP protocol. This allows us to have a common network stack to target all the platforms Delphi supports but to do this in a predictable manner.
This is a fundamental issue with using the platform-native (or integrated) approach to HTTP/S and sockets when you need TLS. While you get the advantage of not distributing OpenSsl, it can lead to unpredictable behavior from device to device and from machine to machine for simple tasks such as hashing, HTTP/S and other operations. How one platform-native HTTP/S client handles asynchronous and/or synchronous requests or parallel threads, can vary widely.
Besides the obvious HTTP/S usage, OpenSsl contains a wealth of useful routines that you can use in your Delphi projects. This article will cover just some of those use cases including using OpenSsl to create random bytes, creating your own X.509 certificates and using OpenSsl for handling JSON Web Tokens (JWT). I like simple, straight-forward examples so this is by no means an exhaustive look at these subjects and is only intended as a primer for using OpenSsl with Delphi.
JSON Web Tokens
JSON Web Tokens are very popular as a way to provide the secure exchange of information between applications in the cloud over just exchanging regular access tokens. They are widely used by many services and APIs available in the cloud like those offered by Google.
Traditionally, access tokens are used in OAuth models. While both access tokens and JWTs are used for similar purposes they each have their own characteristics that make them suitable to certain scenarios. With an access token, typically an implementation needs to track the token and lookup whether it has expired or what other detail is related to the token. At Grijjy, we typically cache tokens into memory and a database and then expire them (delete them) when their expiration interval is up. Access tokens require that all the details of the token are maintained until it is no longer needed.
JWTs work a bit differently. A typical JWT contains all the information related to the token within the token itself. This includes enough information validate that the token is authorized and not expired. JWTs can also contain custom payloads specific to your application. For this purposes they can avoid a round trip to a cache of tokens in memory or in the database for each request. However, processing JWTs with each request and validating them can be a time consuming thing. Quite a few APIs end up mixing both access tokens and JWTs for their APIs.
Personally I feel that JWTs can be very efficient, especially if you validate them one time and then cache them into memory until their expiration is up. That way, with each request you are not validating the entire signature of the JWT again but instead just looking up to see if you previously validated the JWT. A full discussion of tokens is beyond the scope of this article, but we will demonstrate JWTs using at least one hash scheme with OpenSsl.
Note: This is not meant as an exhaustive look at JWTs. We are only demonstrating one algorithm. There are other nice libraries for handling JWTs in Delphi. Our intent is to show how OpenSsl can do this in a simple, straightforward and cross-platform way.
[/SHOWTOGROUPS]