
GIE
π What is GIE and what is it for?
In summary: An encryptor and decryptor for files and folders for Windows, Linux and macOS, written in GO using AES. π GIE is cross-platform, it works on Windows, Linux and macOS.
Example: You can encrypt your file on Windows and decrypt it on Linux or vice versa.
In detail: GIE (Go-based Information Encryptor), is a cross-platform desktop application built using the Wails framework. GIE is designed for the secure encryption and decryption of files and directories, leveraging robust cryptographic primitives implemented in Go. The application aims to provide a user-friendly interface for managing sensitive data.

Version
GIE v1.2.5
π¦ Requirements
- Go v1.24+
- Wails v2.10+
- Node v22.17+
β Features
- Encrypts and decrypts files and folders with AES, for any file type.
- GIE follows a client-server architecture facilitated by the Wails framework.
- Possibility of adding hints.
- Possibility of sharing files between operating systems.
- 3 levels of protection (Low, Normal, High).
- Possibility of adding an encryption channel for greater security.
- Lightweight and easy to use.
- Intuitive and friendly user interface.
- Open Source!
π§βπ» Technical Features
Encrypt and decrypt your files and folders with AES, for any file type: jpg, zip+, mp4, mp3, docx, pdf, etc...
GIE follows a client-server architecture facilitated by the Wails framework. * Frontend (Client): Developed with React (Svelte) and TypeScript, responsible for the user interface and interaction. It communicates with the Go backend through Wails' inter-process communication (IPC) mechanisms. * Backend (Server): Implemented in Go, it handles all the central logic, including file operations, cryptographic processes and system interactions.
GIE employs a hybrid encryption scheme that combines symmetric encryption (AES CTR) for data confidentiality and a Message Authentication Code (HMAC-SHA256) for data integrity and authenticity. Key derivation is performed using PBKDF2.
The encryption and HMAC keys are derived from the user's password using PBKDF2 (Password-Based Key Derivation Function 2) with SHA256 as the pseudorandom function. Separate salts are used for the AES key and the HMAC key to prevent cross-protocol attacks. The number of iterations and the key length are configurable according to the chosen encryption level (Low, Normal, High).
The PBKDF2 function is defined as:
Where:
DK
: Derived KeyPRF
: Pseudorandom Function (HMAC SHA256 in this case)Password
: Password provided by the userSalt
: Random salt (16 bytes)Iterations
: Number of iterations (e.g., 10,000 for Low, 800,000 for Normal, 12,000,000 for High)KeyLength
: Desired length of the derived key (16 bytes for AES-128, 32 bytes for AES-256)
AES in Counter (CTR) mode is used to encrypt the file content. CTR mode transforms a block cipher into a stream cipher, allowing parallel encryption/decryption and direct access to any part of the ciphertext. A unique and randomly generated 16-byte Initialization Vector (IV) is used for each encryption operation. The CTR mode encryption process can be conceptually represented as:
Where:
Ci
: i-th block of ciphertextEK
: AES encryption function with key KNonce
: A unique value for each encryption (part of the IV)Counteri
: A counter that is incremented for each blockPi
: i-th block of plaintextβ
: Bitwise XOR operation
HMAC-SHA256 is used to ensure the integrity and authenticity of the encrypted data and its associated metadata. The HMAC is calculated over the entire encrypted file, including the metadata header (hint length, hint, channel, encryption level code, AES salt, HMAC salt, CTR IV) and the ciphertext. This prevents tampering with both the data and its critical parameters.
The HMAC function is defined as:
Where:
H
: Hash function (SHA256 in this case)K
: Secret key (derived HMAC key)m
: Message (metadata || ciphertext)ipad
: Inner padding (0x36 repeated)opad
: Outer padding (0x5C repeated)||
: Concatenation
Method Structure
Field | Size (Bytes) | Description |
---|---|---|
Hint | Variable | Length of the hint provided by the user for the file |
Channel | 2 | uint16, a user-defined channel for grouping files |
Encryption Level Code | 1 | byte, code representing the encryption strength (0=Low, 1=Normal, 2=High) |
AES Key Salt | 16 | Random salt for AES key derivation |
HMAC Key Salt | 16 | Random salt for HMAC key derivation |
CTR IV | 16 | Random Initialization Vector for AES-CTR |
Ciphertext | Variable | Encrypted content of the original file |
HMAC Tag | 32 | HMAC-SHA256 of all preceding data (metadata + ciphertext) |
GIE provides a robust and secure solution for encrypting files and directories, built on modern cross-platform technologies. Its design prioritizes both security through solid cryptographic practices and usability through a responsive graphical interface.


If you want to know more in depth, you can consult the GitHub Repository for additional details and usage examples. You can also consult with DeepWiki
π» Installation
Run the commands according to your case (Win or Linux)
Clone or download this repository
#BATCH1git@github.com:aiskoa/GIE.git 2
Change directory
#BATCH1cd GIE 2
Install the dependencies
#BATCH1npm install 2
And run
wails build
to compile the application
Make sure you have the latest version of Wails, Node and Go installed on your computer.
ATTENTION!!
If you just want to use it, you can download it from github or from the official site according to your system.
From Official Site: β¬ Download GIE
Minimum Requirements:
- Windows 10/11 / Debian / macOS Ventura or later
- 1 GB of disk space
- 2 GB of RAM
π How to Encrypt?
At the moment it is only available through the GUI.
To Encrypt a folder or file
- Drag or search for the file in the program (Graphical Interface)
- Enter a password (Important to remember it)
- Write a hint for the password (Optional)
- Choose the encryption channel (Optional)
- Choose the encryption level (Optional)
- Click on "Encrypt"
- This converts the file to (.gie)
Once the file is encrypted in .gie it cannot be opened, read or modified. Keep in mind that GIE works for any type of file, even for large files.
π NOTE IF YOU ACCIDENTALLY ENCRYPT ANY FILE OR FUNCTIONALITY OF GIE THE ONLY WAY TO RESTORE IT IS BY REINSTALLING THE PROGRAM!
β οΈβ οΈ IMPORTANT β οΈβ οΈ
- The only way to "recover" the file again is by decrypting it with the GIE program.
- If you want to share the file with your colleague, friend or work team, you will have to provide them with the .gie, the password used and the channel (if applicable).
- IF YOU FORGET OR LOSE THE PASSWORD, YOU WILL NOT BE ABLE TO RECOVER THE FILE IF A HINT WAS NOT WRITTEN.
- IF YOU PUT A CHANNEL YOU MUST ALSO REMEMBER IT OTHERWISE YOU WILL NOT BE ABLE TO RECOVER THE FILE.

π How to Decrypt?
At the moment it is only available through the GUI.
To Decrypt a file
- Drag or search for the (.gie) file in the program (Graphical Interface)
- Enter the password (Required)
- Choose the encryption channel (Optional)
- Click on "Decrypt"
- This converts the file to its natural state
Keep in mind that it will only work for encrypted .gie files. It only works with files encrypted by GIE (Go-based Information Encryptor) current v1.2.5 or higher.
π NOTE IT WILL NOT WORK WITH .GIE FILES VERSION PYTHON, ONLY WITH THE VERSION WRITTEN IN GO!!
- The only way to "recover" the file again is by decrypting it with the GIE program.
- If you want to share the file with your colleague, friend or work team, you will have to provide them with the .gie, the password used and the channel (if applicable).
- IF YOU FORGET OR LOSE THE PASSWORD, YOU WILL NOT BE ABLE TO RECOVER THE FILE IF A HINT WAS NOT WRITTEN.
- IF YOU PUT A CHANNEL YOU MUST ALSO REMEMBER IT OTHERWISE YOU WILL NOT BE ABLE TO RECOVER THE FILE.

Directory encryption function
#GO1func (a *App) EncryptDirectory(dirPath string, password string, hint string, encryptionLevel string, channel int) string { 2 if password == "" { 3 return "Encryption failed: password cannot be empty." 4 } 5 6 // Check if path is actually a directory 7 isDir, err := a.IsDirectory(dirPath) 8 if err != nil { 9 return fmt.Sprintf("Error checking if path is directory: %v", err) 10 } 11 if !isDir { 12 return "Selected path is not a directory." 13 } 14 15 // Get all files in directory 16 files, err := a.GetFilesInDirectory(dirPath) 17 if err != nil { 18 return fmt.Sprintf("Error getting files from directory: %v", err) 19 } 20 21 if len(files) == 0 { 22 return "No files found in directory to encrypt." 23 } 24 25 // Track results 26 var results []string 27 successCount := 0 28 29 for i, file := range files { 30 fmt.Printf("Encrypting file %d/%d: %s\n", i+1, len(files), file) 31 32 result := a.EncryptFile(file, password, hint, encryptionLevel, channel) 33 if result == "success" { 34 successCount++ 35 results = append(results, fmt.Sprintf("β %s", filepath.Base(file))) 36 } else { 37 results = append(results, fmt.Sprintf("β %s: %s", filepath.Base(file), result)) 38 } 39 } 40 41 // Return summary 42 summary := fmt.Sprintf("Directory encryption completed: %d/%d files encrypted successfully", successCount, len(files)) 43 if successCount < len(files) { 44 summary += "\n\nDetailed results:\n" + strings.Join(results, "\n") 45 } 46 47 return summary 48} 49
Directory decryption function
#GO1func (a *App) DecryptDirectory(dirPath string, password string, channel int) string { 2 if password == "" { 3 return "Decryption failed: password cannot be empty." 4 } 5 6 // Check if path is actually a directory 7 isDir, err := a.IsDirectory(dirPath) 8 if err != nil { 9 return fmt.Sprintf("Error checking if path is directory: %v", err) 10 } 11 if !isDir { 12 return "Selected path is not a directory." 13 } 14 15 // Get all .gie files in directory 16 var encryptedFiles []string 17 18 err = filepath.Walk(dirPath, func(path string, info os.FileInfo, err error) error { 19 if err != nil { 20 return err 21 } 22 23 // Only add .gie files 24 if !info.IsDir() && strings.HasSuffix(path, ".gie") { 25 encryptedFiles = append(encryptedFiles, path) 26 } 27 return nil 28 }) 29 30 if err != nil { 31 return fmt.Sprintf("Error scanning directory: %v", err) 32 } 33 34 if len(encryptedFiles) == 0 { 35 return "No encrypted files (.gie) found in directory to decrypt." 36 } 37 38 // Track results 39 var results []string 40 successCount := 0 41 42 for i, file := range encryptedFiles { 43 fmt.Printf("Decrypting file %d/%d: %s\n", i+1, len(encryptedFiles), file) 44 45 result := a.DecryptFile(file, password, false, channel) 46 if result == "success" { 47 successCount++ 48 results = append(results, fmt.Sprintf("β %s", filepath.Base(file))) 49 } else { 50 results = append(results, fmt.Sprintf("β %s: %s", filepath.Base(file), result)) 51 } 52 } 53 54 // Return summary 55 summary := fmt.Sprintf("Directory decryption completed: %d/%d files decrypted successfully", successCount, len(encryptedFiles)) 56 if successCount < len(encryptedFiles) { 57 summary += "\n\nDetailed results:\n" + strings.Join(results, "\n") 58 } 59 60 return summary 61} 62
π Documentation
See the Documentation and User Guides
π Changelog
βοΈ To-Do List
- Password hint
- Theme change
- Android support
- iOS support
- Possibility of use from terminal without GUI (API or MCP)
- Password check
- Reinforced AES
- User interface menu
- Encryption of complete folders and directories