-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
341 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
bin/* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
.PHONY: unix-build | ||
unix-build: ## Build Unix binary | ||
@$(MAKE) build GOOS=darwin GOARCH=arm64 | ||
|
||
.PHONY: win-build | ||
win-build: ## Build Windows binary | ||
@$(MAKE) build GOOS=windows GOARCH=386 | ||
|
||
build: ## Build binary | ||
go build -o ./bin/encryptor | ||
|
||
.PHONY: licenses | ||
licenses: ## Generate LICENSE-DEPENDENCIES.md using golicense binary | ||
@touch LICENSE-DEPENDENCIES.md | ||
@golicense -plain ./bin/prevensys_alerts_center > LICENSE-DEPENDENCIES.md |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
# File Encryption/Decryption tool | ||
|
||
This is a small Go (Golang) application that provides functionality to encrypt and decrypt files using a specified key. | ||
|
||
## Usage | ||
|
||
To use the app, run the following command in your terminal: | ||
|
||
```bash | ||
go run main.go [flags] | ||
``` | ||
|
||
### Flags | ||
|
||
- **-encrypt**: Make encrypt (Specify either -encrypt or -decrypt, not both) | ||
- **-decrypt**: Make decrypt (Specify either -encrypt or -decrypt, not both) | ||
- **-src**: Source file (Provide the path to the source file) | ||
- **-dest**: Destination file (Provide the path to the destination file) | ||
- **-key**: Private key string | ||
|
||
### Examples | ||
|
||
#### Encrypting a File | ||
|
||
```bash | ||
go run main.go -encrypt -src input.txt -dest encrypted.txt -key 770A8A65DA156D24EE2A093277530142 | ||
``` | ||
|
||
or | ||
|
||
```bash | ||
./encryptor -encrypt -src input.txt -dest encrypted.txt -key 770A8A65DA156D24EE2A093277530142 | ||
``` | ||
|
||
#### Decrypting a File | ||
|
||
```bash | ||
go run main.go -decrypt -src encrypted.txt -dest decrypted.txt -key 770A8A65DA156D24EE2A093277530142 | ||
``` | ||
|
||
or | ||
|
||
```bash | ||
./encryptor -decrypt -src encrypted.txt -dest decrypted.txt -key 770A8A65DA156D24EE2A093277530142 | ||
``` | ||
|
||
## Important Notes | ||
|
||
- Please provide both the source and destination file paths. | ||
- **key** flag is mandatory and MUST be a 128-bit. | ||
|
||
## Encryption/Decryption Logic | ||
|
||
This small tool implements symmetric encryption and decryption using the Advanced Encryption Standard (AES) in Galois/Counter Mode (GCM). GCM is a mode of operation for symmetric key cryptographic block ciphers that provides authenticated encryption. Here's a breakdown of the encryption logic: | ||
|
||
### Encryption Logic (Encrypt function): | ||
|
||
1. **Key Generation:** | ||
- The `newGcm` function generates a new Galois/Counter Mode (GCM) cipher using the provided secret key. | ||
- It uses the Advanced Encryption Standard (AES) block cipher with a key derived from the provided secret key. | ||
|
||
2. **Nonce Generation:** | ||
- A nonce (number used once) is generated with a size equal to the nonce size of the GCM cipher. Nonce is a unique value that should only be used once for a given key. | ||
- The nonce is created using a secure random number generator (`rand.Reader`). | ||
|
||
3. **Encryption:** | ||
- The `Seal` method of the GCM cipher is used to encrypt the data. | ||
- The `Seal` method takes the nonce, additional authenticated data (nil in this case), and the plaintext data. | ||
- It returns the ciphertext along with the nonce as the first part of the ciphertext. | ||
|
||
4. **Base64 Encoding:** | ||
- The resulting ciphertext, including the nonce, is encoded using Base64.URLEncoding. | ||
- This encoded string is returned as the encrypted data. | ||
|
||
### Decryption Logic (Decrypt function): | ||
|
||
1. **Key Generation:** | ||
- Similar to the encryption process, the `newGcm` function generates a new GCM cipher using the provided secret key. | ||
|
||
2. **Base64 Decoding:** | ||
- The input encrypted data (received as a Base64-encoded string) is decoded using Base64.URLEncoding. | ||
- The decoded data is stored in the `buf` variable. | ||
|
||
3. **Nonce Extraction:** | ||
- The first part of the `buf` is extracted to obtain the nonce. | ||
|
||
4. **Ciphertext Extraction:** | ||
- The remaining part of the `buf` is considered as the ciphertext. | ||
|
||
5. **Decryption:** | ||
- The `Open` method of the GCM cipher is used to decrypt the data. | ||
- It takes the nonce, additional authenticated data (nil in this case), and the ciphertext. | ||
- It returns the original plaintext. | ||
|
||
### Additional Notes: | ||
|
||
- The `newGcm` function initializes the GCM cipher with the AES block cipher and the provided secret key. | ||
- The nonce size is determined by the GCM cipher and is retrieved using `gcm.NonceSize()`. | ||
|
||
This encryption scheme provides confidentiality and integrity for the data being encrypted. The use of a nonce ensures that the same plaintext encrypted with the same key will produce different ciphertexts, preventing certain types of attacks. | ||
|
||
## License | ||
|
||
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module github.com/OlegChuev/encryptor | ||
|
||
go 1.20 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
package main | ||
|
||
import ( | ||
"github.com/OlegChuev/encryptor/pkg/encryption" | ||
"github.com/OlegChuev/encryptor/pkg/filesystem" | ||
|
||
"flag" | ||
"fmt" | ||
"io/ioutil" | ||
) | ||
|
||
func main() { | ||
encryptFlag, decryptFlag, sourceFlag, destFlag, keyFlag, helpFlag := parseFlags() | ||
|
||
if *helpFlag { | ||
flag.PrintDefaults() | ||
return | ||
} | ||
|
||
if *encryptFlag && *decryptFlag { | ||
fmt.Println("Please specify either -encrypt or -decrypt, not both.") | ||
return | ||
} | ||
|
||
if *sourceFlag == "" || *destFlag == "" { | ||
fmt.Println("Please provide both source and destination file paths.") | ||
return | ||
} | ||
|
||
data, err := ioutil.ReadFile(*sourceFlag) | ||
if err != nil { | ||
fmt.Println("Error reading source file:", err) | ||
return | ||
} | ||
|
||
result, err := process(data, *encryptFlag, *keyFlag) | ||
if err != nil { | ||
var processName string | ||
if *encryptFlag { | ||
processName = "encryption" | ||
} else { | ||
processName = "decryption" | ||
} | ||
|
||
errMsg := fmt.Sprintf("Error during the %s process:", processName) | ||
fmt.Println(errMsg, err) | ||
return | ||
} | ||
|
||
err = filesystem.WriteToFile(*destFlag, result) | ||
if err != nil { | ||
fmt.Println("Error writing to destination file:", err) | ||
return | ||
} | ||
|
||
fmt.Println("Operation completed successfully.") | ||
} | ||
|
||
func parseFlags() (*bool, *bool, *string, *string, *string, *bool) { | ||
encryptFlag := flag.Bool("encrypt", false, "Encrypts data") | ||
decryptFlag := flag.Bool("decrypt", false, "Decrypts data") | ||
sourceFlag := flag.String("src", "", "Source file") | ||
destFlag := flag.String("dest", "", "Destination file") | ||
keyFlag := flag.String("key", "", "Private key string") | ||
helpFlag := flag.Bool("help", false, "Print this help message") | ||
|
||
flag.Parse() | ||
|
||
return encryptFlag, decryptFlag, sourceFlag, destFlag, keyFlag, helpFlag | ||
} | ||
|
||
func process(data []byte, isEncryption bool, key string) (result []byte, err error) { | ||
if isEncryption { | ||
result, err = encryption.Encrypt(data, key) | ||
} else { | ||
result, err = encryption.Decrypt(data, key) | ||
} | ||
|
||
return | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
package encryption | ||
|
||
import ( | ||
"crypto/aes" | ||
"crypto/cipher" | ||
"crypto/rand" | ||
"encoding/base64" | ||
"io" | ||
) | ||
|
||
/* | ||
Encrypt encrypts the given data using the specified secret key. | ||
Parameters: | ||
- data: Data to be encrypted. | ||
- secretKey: Secret key used for encryption. | ||
Returns: | ||
- encoded: Encrypted data. | ||
- err: Error, if any, encountered during the encryption process. | ||
Example Usage: | ||
encryptedData, err := Encrypt(originalData, "yourSecretKey") | ||
if err != nil { | ||
fmt.Println("Encryption failed:", err) | ||
return | ||
} | ||
fmt.Println("Encryption successful. Encrypted Data:", encryptedData) | ||
*/ | ||
func Encrypt(data []byte, secretKey string) (encoded []byte, err error) { | ||
gcm, err := newGcm(secretKey) | ||
if err != nil { | ||
return | ||
} | ||
|
||
nonce := make([]byte, gcm.NonceSize()) | ||
if _, err = io.ReadFull(rand.Reader, nonce); err != nil { | ||
return | ||
} | ||
|
||
cipherText := gcm.Seal(nonce, nonce, data, nil) | ||
encodedData := base64.URLEncoding.EncodeToString(cipherText) | ||
encoded = []byte(encodedData) | ||
|
||
return | ||
} | ||
|
||
/* | ||
Decrypt decrypts the given encrypted data using the specified secret key. | ||
Parameters: | ||
- data: Encrypted data to be decrypted. | ||
- secretKey: Secret key used for decryption. | ||
Returns: | ||
- decoded: Decrypted data. | ||
- err: Error, if any, encountered during the decryption process. | ||
Example Usage: | ||
decryptedData, err := Decrypt(encryptedData, "yourSecretKey") | ||
if err != nil { | ||
fmt.Println("Decryption failed:", err) | ||
return | ||
} | ||
fmt.Println("Decryption successful. Decrypted Data:", decryptedData) | ||
*/ | ||
func Decrypt(data []byte, secretKey string) (decoded []byte, err error) { | ||
gcm, err := newGcm(secretKey) | ||
if err != nil { | ||
return | ||
} | ||
|
||
buf, err := base64.URLEncoding.DecodeString(string(data)) | ||
if err != nil { | ||
return | ||
} | ||
|
||
nonce := buf[:gcm.NonceSize()] | ||
cipherText := buf[gcm.NonceSize():] | ||
decoded, err = gcm.Open(nil, nonce, cipherText, nil) | ||
if err != nil { | ||
return | ||
} | ||
|
||
return | ||
} | ||
|
||
/* | ||
newGcm creates a new Galois/Counter Mode (GCM) cipher for symmetric encryption using the Advanced Encryption Standard (AES). | ||
Parameters: | ||
- secretKey: Secret key used to derive the AES block cipher. | ||
Returns: | ||
- gcm: GCM cipher for encryption and decryption. | ||
- err: Error, if any, encountered during the cipher creation process. | ||
Implementation Details: | ||
- It initializes an AES cipher block with the provided secret key. | ||
- It then creates a GCM cipher using the AES block cipher. | ||
- The resulting GCM cipher is used for secure encryption and decryption. | ||
Example Usage: | ||
gcmCipher, err := newGcm("yourSecretKey") | ||
if err != nil { | ||
fmt.Println("GCM creation failed:", err) | ||
return | ||
} | ||
*/ | ||
func newGcm(secretKey string) (gcm cipher.AEAD, err error) { | ||
block, err := aes.NewCipher([]byte(secretKey)) | ||
if err != nil { | ||
return | ||
} | ||
|
||
gcm, err = cipher.NewGCM(block) | ||
if err != nil { | ||
return | ||
} | ||
|
||
return | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package filesystem | ||
|
||
import ( | ||
"io/ioutil" | ||
) | ||
|
||
func WriteToFile(path string, result []byte) (err error) { | ||
err = ioutil.WriteFile(path, result, 0644) | ||
|
||
return | ||
} |