The Problem

Over the years, I’ve seen a number of situations where Single Sign-On is necessary between applications, but no Commercial Off The Shelf (COTS) solution is available. This is often the case, because the COTS solutions are large, expensive, and require a significant amount of maintenance. Selecting and implementing a COTS solution is usually a company-wide decision and is not undertaken as part of some other, smaller project. However, this doesn’t lessen the frequent need for solid SSO solutions.

Many people try to follow standards of some type (SAML, etc) when implementing SSO, but this often leads right back to the problem of implementing a COTS product locally, not to mention that all SSO partners are required to support the same protocol and version. When dealing with external partners syncing up on SSO protocols and versions can be dicey at best.

To solve this problem, I’ve used a solution I call Simple Single Sign-On that uses a lightweight mechanism to create a cryptographically solid token that can be passed from one entity and validated by another. The system requires nothing more than the standard JDK on both sides as a prerequisite.

First, we’ll discuss what the SSO token must look like. We’ll then cover how a system can be built to create and evaluate those tokens. Lastly, we’ll talk about a few more necessary concepts for supporting the system.

Note: Attached to this post is a zip containing an implementation of the core of the system with the two necessary java keystores. The class itself, SSOUtil contains a main method that demonstrates using the creation and evaluation of the tokens. Download the source and keystores here.

The Token

Token Requirements

Now, let’s discuss what’s required in an SSO token. A valid token requires the following properties:

  • Non-repudiation: the receiver can validate from where/whom a message originates.
  • Message integrity: the receiver can validate that the message has not changed.

Both of the above characteristics are absolute requirements of tokens so that the asserting application can identify a user and then pass that identity on to the receiving application. It’s critical that the receiving party can be sure that it really is the asserting application “vouching” for the user listed in the token.

Enter Digital Signatures

The two properties discussed above can be provided by a digital signature. Digital signatures are made possible by public key cryptography. The key concept of public key cryptography is that the key used to encrypt a message is different than the key used to decrypt a message. This is where public-private key pairs come into play. The private key can encrypt a message and then the public key can decrypt the message and vice-versa.

Just encrypting a message with the private key can form a primitive digital signature. However, there are some security problems associated with just encrypting the message with a private key (i.e. forgery is in the realm of possibility). To address this issue, the message is first run through a cryptographic hash function and then the hash value is encrypted by the private key. The receiving application can then take the same hash of the plaintext and compare it to the decrypted (with the asserter’s public key) hash from the signature. If the two match, then the signature is verified. Note: to validate the signature, the receiving application must be able to access the plaintext message. The image from below describes this process well (click on the image to enlarge):

Digital Signature Operation

Token Transmission

A safe transmission of the token requires the following properties:

  • Message confidentiality: only the sender and receiver can read the message. No external third-party can recover the message.

It is important to keep the token a secret so that third-parties are unable to intercept the token in transit and use it to impersonate the user. If the transmission is not occurring behind a firewall, the best and most common way to achieve this is to transmit the token over an SSL connection (from a defense-in-depth perspective, it’s a good idea to transmit tokens over SSL even behind a firewall).

Token Uniqueness

There’s one more characteristic of a token that is important. The encrypted/signed token should not result in the same string every time for a particular user. If the token is the same every time, then the risk of the token being stolen becomes much, much higher as an attacker only has to steal the token once to be able to log in as the user until the theft is discovered.

To avoid this problem, we need to add in a timestamp to the message so that the encrypted part of the token is different every time. This accomplishes two goals:

  1. The created tokens are different every time
  2. Tokens can expire by having existed for more than a set amount of time.

About the Author

Object Partners profile.

One thought on “Simple Single Sign-On

  1. Bradford says:

    I’m kind of new to the SSO scene, but what’s wrong with CAS?

  2. Robert Kessler says:

    That is definitely the easier way than to have those super heavy systems

Leave a Reply to Robert Kessler Cancel reply

Your email address will not be published. Required fields are marked *

Related Blog Posts
Android Development for iOS Developers
Android development has greatly improved since the early days. Maybe you tried it out when Android development was done in Eclipse, emulators were slow and buggy, and Java was the required language. Things have changed […]
Add a custom object to your Liquibase diff
Adding a custom object to your liquibase diff is a pretty simple two step process. Create an implementation of DatabaseObject Create an implementation of SnapshotGenerator In my case I wanted to add tracking of Stored […]
Keeping Secrets Out of Terraform State
There are many instances where you will want to create resources via Terraform with secrets that you just don’t want anyone to see. These could be IAM credentials, certificates, RDS DB credentials, etc. One problem […]
Validating Terraform Plans using Open Policy Agent
When developing infrastructure as code using terraform, it can be difficult to test and validate changes without executing the code against a real environment. The feedback loop between writing a line of code and understanding […]