Table of Contents
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:
- Create a new directory for your project:
$ mkdir file-encryption-tool $ cd file-encryption-tool
- Initialize a new Go module:
$ go mod init github.com/your-username/file-encryption-tool
-
Create a new Go file named
main.go
and open it in your favorite text editor. - 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" )
- We will define two helper functions
getKey
andgetIV
to generate a random encryption key and initialization vector. Add the following code tomain.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:
- 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 tomain.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") }
- Now, let’s create a
main
function to drive our program. Add the following code tomain.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:
- 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 tomain.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]) }
- Update the
main
function to include the decryption logic. Add the following code tomain.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!