Software DevelopmentDeveloping Secure Applications Part 1 Secure Socket Layer (SSL)

Developing Secure Applications Part 1 Secure Socket Layer (SSL)

Developing Secure Applications Part 1 Secure Socket Layer (SSL)
Introduction

This article is part 1 of a four part series where we look at the issues around developing secure applications. Thousands of hackers work hard to break into our applications try to phish for user information or implant malware. This means as responsible and professional application developers we need to be vigilant about application security to protect users. There are a range of techniques and practices we can employ to enable and enhance application security. In this four part series we will cover at a high level the conceptual basis for these techniques and provide simple source code to illustrate the concepts in a practical way.

In this first part we will look at the Secure Socket Layer (SSL).

The source code for this article can be found here.

Overview

Any application connected to the Internet, such as  a web application or client, an industrial control systems or an Automotive  application, whatever the nature of an Internet connected application it will be vulnerable and exposed to online threats such as viruses, Denial of Service attacks and targeted application or machine compromise attacks..

These threats may come from those seeking to inflict mischievous damage, make money, or Sabotage infrastructure remotely. Best practice, and indeed national regulatory standards such as North American Electric Reliability Corporation (NERC) mandates a strict security. This applies to embedded devices found in industrial and government infrastructure and presents an emerging threat since many devices used in control systems do not support default authentication.

Many programming languages such as Java have strong security policies and implementation., however in the connected space of the internet data in transit is vulnerable to a range of attacks. Using a secure language like Java we can create secure data transfers using Public-key cryptography however this form of data security is vulnerable to a man-in-the-middle attack  (MITM).

Introduction to Transport Layer Security (TLS).

We can protect to a very high degree against a MITM security breach for Public-key encrypted data by following the SSL/TLS standard particularly section 7.4.8. What follows is a very simple outline of what is described in section 7.4.8.

SSL Certificates

SSL Certificates are an extension to the Public-key encryption that include the attribute of identity. This identity can be verified by what is known as a Certificate authority (CA) or signing authority, hence these certificate are sometimes referred to as ‘signed’ or ‘digitally signed’.  This signature is a confirmation or validation by the CA that the public key contained in the certificate belongs to the entity presenting the certificate.  Generally you buy these certificated from a trusted provider however it is also possible to create them yourself, such certificates are often referred to as self-signed.

SSL/TLS Handshake

In the context of the classic client server connection we can use the secure http protocol https which implements the SSL/TLS standard. To initiate this connection over SSL/TLS  we perform what is known as the SSL/TLS handshake. This procedure follow the following pattern.  A client shows a certificate and uses it as part of a Certificate Verify message (as described in section 7.4.8), and the server successfully validates the client certificate with regards to a set of valid attributes such as a private  contained in the trust/key stores.

If the server requests a valid certificate then the client has certainty that as long as the request did not originate from a fake server any further data exchange will be secure to the extent of the Public-key encryption.

If the client presents a valid certificate then the server has a guarantee that it is talking to the right client (the one identified by the client certificate).

Learn by example

What follows is an introduction to using the concepts presented in a practical scenario. We will build a web server and client, then by generating self-signed certificates perform the SSL/TLS handshake to illustrate the principals involved and start to build a vocabulary for all the many details involved in implementing the concepts.

The certificates

Certificates are related to public key cryptography by containing/wrapping a public key.  This public key is paired with a private key. The private key will reside on the server in a keystore.

The easiest way to get started is to use the java Keytool to generate a keystore and self-signed certificate with a private key, then using the play frameworks developer friendly resources easily establish a secure http protocol connection from the client to the play server.

Step 1 – make the keystore, private key and certificate for the public key

keytool -genkey -keyalg RSA -alias selfsigned -keystore keystore.jks -storepass replacethis -validity 360 -keysize 2048

1
Step 2 – export the certificate so the client can use it to authenticate

keytool -export -alias selfsigned  -file mycert.cer  -keystore keystore.jks

2

now you should have the following files, a keystore for the play server “keystore.jks“  and a certificate for the client “mycert.cer”  as shown below. We will use these in the source code.

3

The Server

We will use the Play Framework to build simple play server with ssl configuration. The Play framework is chosen to code the server due to its excellent SSL integration.

Step 1

Install the latest version of the Simple Build Tool sbt for your operating system from here.

Step 2

You need to copy the “keystore.jks“keystore for the play server into the PlayServer/conf directory as shown below

4

Step 3 Build the server

We only need the Simple Build Tool (sbt) to build the Play server.

Change into the Play Server directory  and issue the following sbt build commands from a terminal.

sbt clean compile

The first time you build the code it takes a while for sbt to download all the play framework dependencies, however subsequent builds are faster

5

Step 4

Build the server uber jar with the sbt one jar task.

sbt one-jar

6

in the “PlayServer/target/scala-2.10/” directory you should see the eduonixssl_2.10-1.0-one-jar.jar  uberjar as shown below

7

Copy this and rename it to something useful like “eduonixssl.jar”. There is an Ant file that will do this and output to a staging directory if you are ok with ant (see the Eduonix java build tools blog for more information on how to automate routine build tasks with ant).

Step 5

Run the server

In the directory where you copied and renamed the uber jar you can run the server with

java -jar eduonixssl.jar

8

The client

We will use the Apache HttpComponents™ project to build a client with ssl configuration.
You need to copy the “mycert.cer” certificate for the client into the src/main/resources  directory as shown below
9

Perform the SSL/TLS handshake

Step 1

Run the play server and you see it creates the keystore in the same directory as the jar as well as a logs directory  and a RUNNING_PID file

10

Step 2

Run the client main class  EntryPoint.java in your ide for convenience you should see the output of the ssl/tls handshakke below.
11

Then the secure https get request followed by some html
Then the play server reports the secure connection can be kept alive for further requests
12

this exercise was useful as it illustrated the following

  • The Play Framework is a good rapid application environment for creating a rest api
  • Apache Httpcomponents is good rapid application environment for creating a client
  • Configuring the Play Framework server with the “jks“ containing the private key and client certificate for authentication was trivial
  • Creating the ssl/tls connection to the play server and presenting the “mycert.cer” certificate for authentication was more code but compared to other frameworks was simple.

We will now step through the key parts of the source code that facilitated the ssl/tls handshake.

Key SSL/TLS concepts in the Play Framework Rest Server Codebase

Now we will look at the key play code that configures the ssl/tls connector.

We place the certificate in the Play server conf directory.  Then in the servers EntryPoint
Class we simply set the following system properties.

First we set the secure and open http ports

System.setProperty("http.port", "9001");
System.setProperty("https.port", "9443");

Then we test for the presence of a Keystore, if one exists we use it otherwise copy in the new updated store

File file = new File("keystore.jks");
if(!file.exists()){
InputStream is = EntryPoint.class.getResourceAsStream("keystore.jks");
File keystore = new File("keystore.jks");
Files.copy(is, keystore.toPath(), StandardCopyOption.REPLACE_EXISTING);
Logger.info("Keystore does not exist locally. Copying into local directory.");
} else{
Logger.info("Keystore exists locally. Using local keystore."); }

Once we have set up the keystore we set system properties for its location and password

System.setProperty("https.keyStore", "keystore.jks");
System.setProperty("https.keyStorePassword", "replacethis");

Now the Play frameworks Netty server is configured for ssl/tls.

Key SSL/TLS concepts in the Apache HttpComponents™  Client Codebase

The EntryPoint class calls the rest server via a secure ssl/tls rest client.

SSLManager sslConnection = new SSLManager();
sslConnection.doGet( );

Unlike the play server framework we need to write more code to create our own secure rest client we do this in the SSLManager class. This class creates an ssl/tls connection to the server with an instance of the CloseableHttpClient from the Apache HttpComponents™ project. CloseableHttpClient is the base class of the httpclient library, you can read more about the relationship between the various artifacts of here

CloseableHttpClient </strong><strong>client = HttpClients.<em>custom</em>()
.setSSLSocketFactory(sslsf)
.setDefaultCookieSpecRegistry(r)
.setDefaultRequestConfig(requestConfig)
.build();

We construct our secure client using the Factory methods found in the HttpClients class. To use this client factory we must create the following types

First we create a certificate factory and parse the certificate and check the format, this is a critical step, if we are tricked into loading a fake certificate we are basically hacked.

CertificateFactory cf = CertificateFactory.<em>getInstance</em>(<strong>"X.509"</strong>);
InputStream caInput = SSLManager.<strong>class</strong>.getClassLoader().getResourceAsStream(<strong>"mycert.cer"</strong>);
Certificate ca = cf.generateCertificate(caInput);

Then we create a trustmanager and a SSL context

<em>// Create a TrustManager that trusts the CAs in our KeyStore</em>
String tmfAlgorithm = TrustManagerFactory.<em>getDefaultAlgorithm</em>();
TrustManagerFactory tmf = TrustManagerFactory.<em>getInstance</em>(tmfAlgorithm);
tmf.init(keyStore);
<em>// Create an SSLContext that uses our TrustManager</em>
SSLContext context = SSLContext.<em>getInstance</em>(<strong>"TLS"</strong>);
context.init(<strong>null</strong>, tmf.getTrustManagers(), <strong>null</strong>);
SSLContext sslcontext = SSLContexts.<em>custom</em>()
.loadTrustMaterial(keyStore, <strong>new </strong>TrustSelfSignedStrategy())
.build();

Now we are in a position to set up the  SSLSocketFactory

SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslcontext,
new String[]{"TLSv1"},
null,
new HostnameVerifier() {
public boolean verify(String s, SSLSession sslSession) {
return s.equals(<em>HOST_NAME</em>);
}   });

Now we follow similar steps using builders for the CookieSpecProvider and RequestConfig types. From a security perspective these are less critical, the key security vulnerability here is the integrity of the CertificateFactory code block.

Certificate ca = cf.generateCertificate(caInput);

Now we have successfully configured the secure client we can use it for rest calls to the rest server.

HttpGet get = new HttpGet(BASE_URL);
CloseableHttpResponse closeableHttpResponse = closeableHttpResponse = client.execute(get);

Hopefully if you are new to coding rest applications this code base and article can be used as a guide and bootstrap code for building a secure rest application. Along the way we have introduced you to the Play framework and the Simple Build Tool.

Summary

This article and coding exercise was just an overview and introduction to the terminology and basic ideas. Then we worked through some simple code to implement the ideas and illustrate the concepts.

For professional practice you need to go a lot further due to the prevalence of hostile agents and the security of you or your client’s data. For example at a basic minimum you should check whether a certificate has been issued by a trusted source instead of just considering whether it is currently valid,  you can easily check whether a certificate was self-signed as self-signed certificates will always fail OpenSSL’s validation.

The terminology of SSL Certificates is extensive. Certificates can contain extensions such as Subject Alternative Names (SAN) which allow you to specify a list of host names to be protected by a single SSL certificate. This is important as certificates obtained from a CA are expensive and only last for a set time period.

This concludes our introduction to securing an application with SSL/TLS. In the Part 2 we’ll look at how an application can authenticate their users across websites and apps without having to own and manage password files using OpenID from the OpenID Foundation.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Exclusive content

- Advertisement -

Latest article

21,501FansLike
4,106FollowersFollow
106,000SubscribersSubscribe

More article

- Advertisement -