Developing a Command-Line File Encryption Tool in Go

Table of Contents

  1. Introduction
  2. Prerequisites
  3. Setting up the Project
  4. Implementing Encryption
  5. Implementing Decryption
  6. Conclusion


Introduction

In this tutorial, we will develop a command-line file encryption tool using Go. The tool will allow the user to encrypt and decrypt files using a symmetric encryption algorithm. By the end of this tutorial, you will have a fully functional file encryption tool that can be used to secure your sensitive files.

Prerequisites

Before you begin this tutorial, you should have a basic understanding of Go programming language. Additionally, you should have Go installed on your system.

Setting up the Project

Let’s start by setting up the project structure. Open your terminal and follow these steps:

  1. Create a new directory for your project:
     $ mkdir file-encryption-tool
     $ cd file-encryption-tool
    
  2. Initialize a new Go module:
     $ go mod init github.com/your-username/file-encryption-tool
    
  3. Create a new Go file named main.go and open it in your favorite text editor.

  4. Add the following code to main.go to import the required packages:
     package main
        
     import (
     	"bufio"
     	"crypto/aes"
     	"crypto/cipher"
     	"crypto/rand"
     	"io"
     	"log"
     	"os"
     )
    
  5. We will define two helper functions getKey and getIV to generate a random encryption key and initialization vector. Add the following code to main.go:
     func getKey() []byte {
     	key := make([]byte, 32)
     	if _, err := rand.Read(key); err != nil {
     		log.Fatal(err)
     	}
     	return key
     }
        
     func getIV() []byte {
     	iv := make([]byte, aes.BlockSize)
     	if _, err := rand.Read(iv); err != nil {
     		log.Fatal(err)
     	}
     	return iv
     }
    

    With the project setup complete, we can now move on to implementing the encryption and decryption functionalities.

Implementing Encryption

To encrypt a file, we will use the AES encryption algorithm in the Counter (CTR) mode. Follow these steps to implement the encryption logic:

  1. Create a new function encryptFile that takes the file path, encryption key, and initialization vector as arguments. This function will handle the encryption process. Add the following code to main.go:
     func encryptFile(filePath string, key []byte, iv []byte) {
     	file, err := os.Open(filePath)
     	if err != nil {
     		log.Fatal(err)
     	}
     	defer file.Close()
        
     	ciphertextFile, err := os.Create(filePath + ".enc")
     	if err != nil {
     		log.Fatal(err)
     	}
     	defer ciphertextFile.Close()
        
     	block, err := aes.NewCipher(key)
     	if err != nil {
     		log.Fatal(err)
     	}
        
     	stream := cipher.NewCTR(block, iv)
        
     	reader := bufio.NewReader(file)
     	writer := bufio.NewWriter(ciphertextFile)
        
     	for {
     		plaintext := make([]byte, aes.BlockSize)
     		bytesRead, err := reader.Read(plaintext)
     		if err != nil {
     			if err == io.EOF {
     				break
     			}
     			log.Fatal(err)
     		}
        
     		ciphertext := make([]byte, bytesRead)
     		stream.XORKeyStream(ciphertext, plaintext[:bytesRead])
     		_, err = writer.Write(ciphertext)
     		if err != nil {
     			log.Fatal(err)
     		}
     	}
        
     	err = writer.Flush()
     	if err != nil {
     		log.Fatal(err)
     	}
        
     	log.Printf("Encryption complete. Encrypted file saved as %s", filePath+".enc")
     }
    
  2. Now, let’s create a main function to drive our program. Add the following code to main.go:
     func main() {
     	key := getKey()
     	iv := getIV()
        
     	// Replace filePath with the path to the file you want to encrypt
     	filePath := "/path/to/file.txt"
        
     	encryptFile(filePath, key, iv)
     }
    

Implementing Decryption

To decrypt the encrypted file, we will use the same encryption key and initialization vector used during the encryption process. Follow these steps to implement the decryption logic:

  1. Create a new function decryptFile that takes the encrypted file path, encryption key, and initialization vector as arguments. This function will handle the decryption process. Add the following code to main.go:
     func decryptFile(filePath string, key []byte, iv []byte) {
     	encryptedFile, err := os.Open(filePath)
     	if err != nil {
     		log.Fatal(err)
     	}
     	defer encryptedFile.Close()
        
     	decryptedFile, err := os.Create(filePath[:len(filePath)-4])
     	if err != nil {
     		log.Fatal(err)
     	}
     	defer decryptedFile.Close()
        
     	block, err := aes.NewCipher(key)
     	if err != nil {
     		log.Fatal(err)
     	}
        
     	stream := cipher.NewCTR(block, iv)
        
     	reader := bufio.NewReader(encryptedFile)
     	writer := bufio.NewWriter(decryptedFile)
        
     	for {
     		ciphertext := make([]byte, aes.BlockSize)
     		bytesRead, err := reader.Read(ciphertext)
     		if err != nil {
     			if err == io.EOF {
     				break
     			}
     			log.Fatal(err)
     		}
        
     		plaintext := make([]byte, bytesRead)
     		stream.XORKeyStream(plaintext, ciphertext[:bytesRead])
     		_, err = writer.Write(plaintext)
     		if err != nil {
     			log.Fatal(err)
     		}
     	}
        
     	err = writer.Flush()
     	if err != nil {
     		log.Fatal(err)
     	}
        
     	log.Printf("Decryption complete. Decrypted file saved as %s", filePath[:len(filePath)-4])
     }
    
  2. Update the main function to include the decryption logic. Add the following code to main.go:
     func main() {
     	key := getKey()
     	iv := getIV()
        
     	// Replace filePath with the path to the encrypted file you want to decrypt
     	filePath := "/path/to/encrypted-file.txt.enc"
        
     	decryptFile(filePath, key, iv)
     }
    

Conclusion

In this tutorial, we have developed a command-line file encryption tool using Go. You now have a fully functional tool that can encrypt and decrypt files using the AES encryption algorithm in the Counter (CTR) mode. You can use this tool to secure your sensitive files and protect them from unauthorized access.

Remember to handle the encryption key and initialization vector securely, as they are essential for decrypting the encrypted files. Always keep backups of your encryption key and IV in a safe place.

Feel free to explore more advanced encryption techniques or integrate this tool into larger applications for additional functionality. Happy coding!