Home » Blog » How to create secure keys for symmetric encryption?

How to create secure keys for symmetric encryption?


Secure keys creation is a topic of utmost importance in Cryptography and Network Security. The stronger the keys the better, the more secure your data will be.

But, how to create strong keys/passwords?

In classic cryptography, we were expected to create the keys used for encryption. For instance, Caesar Shift Cipher uses an integer number (the sift) as the key/password for encryption. In the case of other substitution ciphers and transposition ciphers, you can use any key phrase.

The general recommendation about these keys/passwords was to use long enough passwords that are not common (12345678 is a very bad one) so a brute force attach gets more difficult. The longer the key the more difficult a brute force attack is.

Now, in modern cryptography, we hear about 128-bit keys.

So, many ask the following question: how many characters do we have to write to have a 128-bit key?

In modern cryptography, we do not create the keys manually. The software does it for us. The reason behind it is because is (time) expensive to create them manually.

Keep reading so you understand how keys are created nowadays, for use in modern cryptography algorithms.

Type of keys used in cryptography

In cryptography, we can generate two types of keys. Namely keys for symmetric encryption and keys for asymmetric encryption.

We must differentiate the two types of keys because symmetric encryption uses only one key. But asymmetric encryption uses a pair of keys that are related.

So, the process is different in both cases.

Create keys of a specific bit length in python for symmetric encryption

Secure Keys creation might vary from library to library. I will give you a few examples of how is done in python.

In Python, we have several utilities for creating pseudo-random numbers:

  • random module: not suitable for cryptographic purposes. Designed for modeling and simulations.
  • os.random(): not suitable for cryptographic purposes.
  • os.urandom(size): suitable for cryptographic purposes.
  • secrets module. Can be used to create cryptographically strong random numbers suitable for passwords, account authentication, security tokens, and related secrets.

The function us.urandom(size) takes as a parameter the size in bytes. Notice that 1 byte equals 8 bits.

128-bit key length creation

import os

random_key = os.urandom(16)
print('bytes:')
print (random_key)

number = int.from_bytes(random_key, byteorder="big")
print('number:')
print (number)
print('Number of digits in the number:')
print (len(str(number)))

192-bit key length creation

import os

random_key = os.urandom(24)

256-bits key length creation

import os

random_key = os.urandom(32)

We can also use the module secrets to create random numbers of 128-bits, 192-bits, and 256-bits among others. See the example below.

import secrets

random_key = secrets.randbits(128)
print (random_key)

random_key = secrets.randbits(192)
print (random_key)

random_key = secrets.randbits(256)
print (random_key)

How to create a 256-bit key from a password?

A Key Derivation Function (KDF) is a cryptographic algorithm that takes a value as input (password, passphrase, master key, etc.) and returns a key of a specific length. You can think of it as a key stretching function.

With this type of function, we do not need to know how many characters or numbers we need to write to create a specific size (128-bit, 256-bit, etc.) key.

In this case, I’m going to use a kdf implementation from the cryptography Python module.

import os
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
# Salts should be randomly generated
salt = os.urandom(24)
# derive
kdf = PBKDF2HMAC(
    algorithm=hashes.SHA3_256(),
    length=32,
    salt=salt,
    iterations=10000,
)
key = kdf.derive(b"key phrase")
print (key)
print(len(key)

The most important parts of the code above are the parameters of the class PBKDF2HMAC.

  • algorithm – An instance of a Hash Algorithm,
  • length (int) – The length of the derived key in bytes.
  • salt (bytes) – A salt. Secure values are 128-bits (16 bytes) or longer and randomly generated.
  • iterations (int) – The number of iterations to perform the hash function. This can be used to control the length of time the operation takes. Higher numbers help mitigate brute force attacks against derived keys.

Notice that I used length=32 to create a key of 256 bits. In this case the length parameter is in bytes (1 byte = 8 bits). You should pay attention to how libraries are implemented. Some of them use as a parameter the number of bits, others the number of bytes.

Creating secure passwords

In the section above, I showed you how to create a key of a specific bit size from a password. However, whatever password you use for that should be strong. The stronger the password the better.

Modern browsers give you the option to create a strong password for you as well as other software when you are creating an account for the first time. Developers have incorporated this functionality because of the importance of having strong passwords to protect our accounts and confidential information.

You can also create such types of passwords within your code by using existing libraries. These passwords can then be used to create specific bit-sized keys for symmetric encryption.

Find below an example using Python.

import string
import secrets
special = '@!#$%^&*'
alphabet = string.ascii_letters + string.digits + special
while True:
    password = ''.join(secrets.choice(alphabet) for i in range(10))
    if (any(c.isupper() for c in password)
            and any(c in special for c in password)
            and sum(c.isdigit() for c in password) >= 3):
        break
print (password)

In this case, I’m creating a 10-character password with at least one uppercase character, one special character, and at least three digits.

See a sample of output below.

Example of strong random passwords created in Python
Example of strong random passwords created in Python

As you can see, it will be difficult for anyone to guess one of the previous passwords.

Summary

As a summary, you should remember this:

  • Modern symmetric cryptographic algorithm creates secure keys for you. You shouldn’t do it manually.
  • You can create a relatively small password and, using that password you can create a key of specific bits size for symmetric encryption algorithms.
  • Passwords should be created as randomly and secure as possible. You can generate a secure random password and then use it to create the key you need for the symmetric encryption algorithm.
  • Always try to use open-source software when using cryptographic algorithms. This type of code is usually reviewed by thousands of programmers and usually are safe to use. As a plus, you can also check the code and find out how the algorithms are implemented.
  • Always use standard algorithms.

Related content