Encrypt and Decrypt Data in Go with AES-256
Time to read: 5 minutes
Encrypt and Decrypt Data in Go with AES-256
Safeguarding sensitive information is a cornerstone of secure application development! Its importance cannot be overstated — especially in today's world where cyber threats constantly evolve. Secure development practices are no longer optional – they are essential for protecting user privacy, preventing data breaches, and ensuring the overall trustworthiness of your application.
In the Go programming language, understanding how to encrypt and decrypt data is crucial for implementing robust security measures.
In this article, you'll go through the process of encrypting and decrypting data using AES-256 (Advanced Encryption Standard) encryption in Go, leveraging the standard library's crypto/aes and crypto/cipher packages.
Prerequisites
Before diving into encryption and decryption, ensure you have the following available:
- Go installed on your machine
- A terminal emulator
- A text editor
- A basic understanding of Go programming
- Some prior knowledge of encryption would be helpful, but is not necessary
Encrypt data using AES-256
AES-256 encryption is a highly secure symmetric encryption algorithm that uses a 256-bit key to encrypt data. The process of AES-256 encryption is designed to ensure the highest level of security, making it highly resistant to brute-force attacks and other forms of cyber threats.
The AES-256 encryption process begins by dividing the plaintext, or original, data into blocks 128 bits in size. To break this down, AES arranges the data to be encrypted in a 4x4 grid where each cell contains 16 bytes. Given that each byte is composed of 8 bits, the total bit count within each block is precisely 128 bits. This allows the algorithm to operate on manageable chunks of data. The data is then transformed into ciphertext through a series of rounds.
Rounds refers to the multiple stages of processing that the plaintext undergoes to be transformed into ciphertext. Each round involves a complex series of operations like substitution and permutation, all aimed at scrambling the original data (plaintext) into an unreadable format (ciphertext), making it practically impossible to reverse without the correct key. This process is designed to be secure and complex, making it highly resistant to brute-force attacks.
In AES, the size of encrypted data remains constant. This means that it takes 128 bits of the data and encrypts it into 128 bits of ciphertext.
AES-256 encryption offers several key advantages, some of which include:
- Complexity Enhancement: AES-256 uses a unique key for each round, significantly increasing encryption complexity and making it resistant to brute-force attacks 2
- Nonlinear Data Modification: It employs byte substitution, obscuring the relationship between plaintext and ciphertext, enhancing security against cryptanalysis 2
- Data Diffusion: Through shifting rows and mixing columns, AES-256 diffuses data, complicating encryption and ensuring encrypted data doesn't retain any direct relationship with the original plaintext
Due to its exceptional strength, AES-256 is widely used by governments, militaries, and financial institutions to protect their most sensitive information.
Open up the terminal and create a folder for this project.
Next, inside the folder, create a file called main.go. Then, in the file, add the following code:
In the code above, we prepared the data we want to encrypt, which is a string, and then converted it into a byte slice because AES cryptographic algorithms require data to be in a binary format, meaning it needs to be expressed in a sequence of 0’s and 1’s.
We then enhanced the security of our data by generating a 32-byte encryption key. This step is important, especially for AES-256 encryption, because it requires exactly a 32-byte key length. The length of this key is directly tied to the security and the complexity of the encryption process. In simpler terms, the longer the key, the more resistant it is to security breaches.
Afterward, we created the encryption key using the byte slice and then used the `rand.Reader.Read()` to ensure that our key was secure and composed of random numbers.
Next, we’ll create an AES-256 block cipher. Think of it as a fundamental tool for keeping data secure. This cipher processes data in fixed 128-bit blocks, which is similar to a lock and key system. The block is like a lock, and our key is the secret code used to access it.
We’ll use the crypto/aes package to make this happen. Once again, the block cipher is vital because it lays the foundation of data security. It processes our data in fixed-size blocks, adding a strong protection layer.
Right after the error handling block at the end of main()
, add the following code:
Use GCM For enhanced security
Now, we’ll introduce the GCM (Galois/Counter Mode), a powerful encryption method. GCM is a cryptographic mode of operation that combines the security of a symmetric block cipher (like AES) with message authentication.
GCM does two key things. First, it encrypts data, making it unreadable to unauthorized eyes. Second, it generates a tag (checksum) that verifies the data's integrity during decryption. Any modification to the ciphertext will result in a verification failure.
In simple terms, using GCM is like adding a digital seal to our encrypted data. This ensures that it remains intact and not tampered with during transmission. We’ll set the GCM using the crypto/cipher package, by adding the following code below to the end of main()
:
Generate a NONCE
You next need to create a nonce, which stands for "number used once". It is a random or pseudo-random value used along with a GCM for cryptographic operations. A nonce is a crucial part of the encryption process. It's a unique value used only once for each encryption. This helps ensure the confidentiality of the data and prevent replay attacks.
Add the code below to the end of the main()
function.
The nonce ensures that every encryption operation is unique and secure. Think of a nonce as a unique identifier for each encryption, like a lottery ticket number. It ensures that even if we encrypt the same data multiple times, each encryption is unique and secure. We’ll generate one and fill it with unpredictable data using the crypto/rand package.
Now, we'll use the gcm.Seal()
function to turn our data into a secure, unreadable form to protect it from prying eyes by adding the code below to the end of the main()
function.
Convert the ciphertext to hexadecimal
The last step is to convert the ciphertext to hexadecimal and print out the result. All that you need to do is add the following to the end of main()
.
So, in our encryption process, we prepped the data for encryption, generated a secure 32-byte encryption key, created an AES block cipher, used GCM mode for encryption, and finally generated and utilized the nonce to ensure the uniqueness of each encryption operation.
Decrypt data using AES-256
Now that we've encrypted our data, we need to know how to decrypt it and retrieve the original information. Decryption involves, effectively, reversing the encryption process. We'll need the same encryption key and other parameters used during encryption to decrypt the data successfully.
In short, to decrypt the data we'll:
- Convert the ciphertext from hexadecimal back to binary format
- Create the AES block cipher using the same encryption key
Use the GCM mode to decrypt the ciphertext and retrieve the original plaintext
Right after the code that converts to hexadecimal, add the following code
In the code above, we decode the hexadecimal ciphertext to obtain the original binary data. We then create a new instance of the AES block cipher and GCM mode using the same key and nonce. Finally, we use the gcm.Open()
function to decrypt the ciphertext, producing the original plaintext.
Print the decrypted data. After the code that prints the encrypted data, add this:
Test the Application
Run the code in the terminal using the go run command:
Below is a screenshot of the output:
You have successfully encrypted and decrypted data in Go!
Conclusion
In this tutorial, we learned how to encrypt and decrypt data using AES-256 in Go. We used the crypto package to perform encryption and decryption operations. We also discussed the importance of using a secure random number generator for generating keys and nonces.
Temitope Taiwo Oyedele is a software engineer and technical writer. He likes to write about things he’s learned and experienced.
Related Posts
Related Resources
Twilio Docs
From APIs to SDKs to sample apps
API reference documentation, SDKs, helper libraries, quickstarts, and tutorials for your language and platform.
Resource Center
The latest ebooks, industry reports, and webinars
Learn from customer engagement experts to improve your own communication.
Ahoy
Twilio's developer community hub
Best practices, code samples, and inspiration to build communications and digital engagement experiences.