As software developers, an integral part of our value we add for our clients is ensuring their system, and their data is private and secure. We can thank cryptography, a mathematical technique which provides data confidentiality and integrity, for helping us provide this security.
Cryptography is used everywhere on the internet and in enterprise. Clients understand and appreciate the need to protect data, communication and online financial transactions in both their personal lives and in business.
I will be summarising the three most common types of cryptography - hashing, symmetric key encryption and public key encryption with examples for the applications for each method, based on our clients’ own business requirements.
Hashing is a function that can be used to map messages into a series of unreadable characters of a fixed size, the values returned by a hash function are called hash values. Hash values are collision-resistant. That means for a given hash function, it always maps the same input message into an identical hash value. Whereas for different input messages, a hash function will rarely return the same hash value. Hash functions are also non-reversible, which means there is no way to tell what the input message is based on the hash result.
The unique properties of hash functions discussed above make them perfectly suitable for securing password storage. Storing the hashed value of passwords instead of plain text adds a layer of protection, but still allows us to authenticate the users.
The image above shows user passwords stored in plain text vs hash value. If unintended people obtain the list of user password hashes, they can’t retrieve the original passwords based on the hash values.
But hashing alone isn’t good enough. Although hash functions are non-reversible, there are a lot of different ways to hack them. Passwords and their corresponding hash values can be easily precomputed and stored in a lookup table. To reverse the password hash, attackers can query each of the hashes in the lookup table.
A better approach to prevent these kinds of attacks is to use salt with these hash functions. Salt is a randomly generated string and usually stored in plain text in the user table. Each password needs to be concatenated with a unique salt before hashing to randomise the output. Attackers couldn’t precompute a hash lookup table because they wouldn’t know which salt was used at the time they built their lookup table.
However, with modern High-end GPUs, attackers can compute billions of hashes per second, so they can actually brute-force hash values with the salt. The best password protection technique nowadays is called key stretching. Key stretching is a particular type of CPU-intensive hash function which runs very slowly.
Here at Sandfield, we ensure our user passwords are stored with a robust hash algorithm with salt. We also have a library that implements PBKDF2, which is an algorithm that provides key stretching function to add additional computational work to make password cracking much more difficult. Some of our customers use the same technique.
The second type of cryptography is encryption which also maps messages into a series of unreadable characters. Still, the encrypted message can be reversed back into their original decrypted form (hashing can’t do this). There are two types of encryption: symmetric key encryption and public key encryption.
Symmetric key encryption
In symmetric key encryption, the exact same key is used to perform encryption and decryption. It is much faster and more secure to run for a given key length compare to public key encryption. Therefore, it should always be used whenever possible. The challenge for secret key cryptography is that it requires sophisticated mechanisms to securely distribute the secret key across two parties.
Public key encryption
In contrast, public key encryption uses two different keys (public key and private key). Either key can be used for encrypting messages, and only the other matching key can decrypt the encrypted messages. The public key can be shared to anyone, however, the private key needs to be kept secret. Public key encryption is usually only used to establish a secure connection to exchange the secret key which will then be used to perform the symmetric key encryption on actual messages.
All three types of cryptography have their strengths, and we at Sandfield are careful about deciding which model to use and for what application, balancing the optimal with the pragmatic.
As standard practice, our password protection is hash-salt-key stretching. We’ve invested in our library that implements PBKDF2 with key stretching size of 10K to be able to support our clients this way, but we recognise that these libraries are not completely fail-safe.
Outside of password protection, we use symmetric encryption to store sensitive information in a database such as a third-party API token and decrypt them in an application when they need to be used. Symmetric key encryption is a better option in this case because the token is only for internal use, and we always have access to the secret key when performing encryption or decryption.
Public key encryption is less often used at Sandfield because we rarely have to establish our own secure channel to exchange information with external parties. In the cases that we do, many well-established protocols can be used such as HTTPS.
HTTPS is an implementation of both public key encryption and symmetric key encryption. When we visit a website over https, our browser initiates SSL handshake with a server, The server will return its public key. Our browser then creates a secret key, encrypts it using the server’s public key and send it to the server. Because the server holds the corresponding private key, it can decrypt the secret key into plain text. After both the browser and the server have the secret key, they can encrypt and decrypt requests and responses using it.
Hashing, symmetric key encryption and public key encryption are three different types of cryptography. Each of them serves a different purpose, but they can be used in combination to meet the security requirements for the software. Our position on the most suitable cryptography methodologies is continually evolving, as are the methods designed to break the cryptography algorithm. The lesson here is to re-evaluate practices and remain one step ahead.