Skip to content

Commit c43e3b3

Browse files
authored
Merge pull request #7 from sd416/1.4
Short flag support
2 parents 634fd2e + 935af2c commit c43e3b3

File tree

5 files changed

+190
-63
lines changed

5 files changed

+190
-63
lines changed

README.md

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ File Encryptor is a command-line tool written in Go that provides secure file en
1313
- Support for **all file types**: text, images (JPG, PNG), videos, spreadsheets, and more
1414
- Parallel processing for faster encryption and decryption of large files
1515

16-
**File Support Note**:
16+
**File Support Note**:
1717
- The tool supports all file types, including:
1818
- **Text**: TXT, CSV, JSON
1919
- **Media**: JPG, PNG, MP4
@@ -32,7 +32,7 @@ Example usage ensures seamless encryption and decryption without data corruption
3232

3333
2. Clone this repository:
3434
```bash
35-
git clone https://github.com/yourusername/file-encryptor.git
35+
git clone https://github.com/sd416/file-encryptor.git
3636
```
3737

3838
3. Navigate to the project directory:
@@ -42,7 +42,7 @@ Example usage ensures seamless encryption and decryption without data corruption
4242

4343
4. Build the project:
4444
```bash
45-
go build -o file-encryptor main.go
45+
go build -o file-encryptor cmd/file-encryptor/main.go
4646
```
4747

4848
## Usage
@@ -60,21 +60,29 @@ ssh-keygen -t rsa -b 4096 -f my_ssh_key
6060

6161
#### Encrypt a file using an RSA public key:
6262
```bash
63-
./file-encryptor -e --file <input_file> --key my_ssh_key.pub
63+
./file-encryptor -e --file <input_file> --key <public_key_file>
64+
# or using short flags
65+
./file-encryptor -e -f <input_file> -k <public_key_file>
6466
```
6567
Example:
6668
```bash
6769
./file-encryptor -e --file picture.jpg --key my_ssh_key.pub
70+
# or
71+
./file-encryptor -e -f picture.jpg -k my_ssh_key.pub
6872
```
6973
- The encrypted file will be saved as `picture.jpg.enc`.
7074

7175
#### Encrypt a file using a password:
7276
```bash
7377
./file-encryptor -e --file <input_file> --password <your_password>
78+
# or using short flags
79+
./file-encryptor -e -f <input_file> -p <your_password>
7480
```
7581
Example:
7682
```bash
7783
./file-encryptor -e --file document.pdf --password myStrongPassword123
84+
# or
85+
./file-encryptor -e -f document.pdf -p myStrongPassword123
7886
```
7987

8088
---
@@ -83,21 +91,29 @@ Example:
8391

8492
#### Decrypt a file using an RSA private key:
8593
```bash
86-
./file-encryptor -d --file <encrypted_file> --key my_ssh_key
94+
./file-encryptor -d --file <encrypted_file> --key <private_key_file>
95+
# or using short flags
96+
./file-encryptor -d -f <encrypted_file> -k <private_key_file>
8797
```
8898
Example:
8999
```bash
90100
./file-encryptor -d --file picture.jpg.enc --key my_ssh_key
101+
# or
102+
./file-encryptor -d -f picture.jpg.enc -k my_ssh_key
91103
```
92104
- The decrypted file will retain its original extension (e.g., `picture.jpg`).
93105

94106
#### Decrypt a file using a password:
95107
```bash
96108
./file-encryptor -d --file <encrypted_file> --password <your_password>
109+
# or using short flags
110+
./file-encryptor -d -f <encrypted_file> -p <your_password>
97111
```
98112
Example:
99113
```bash
100114
./file-encryptor -d --file document.pdf.enc --password myStrongPassword123
115+
# or
116+
./file-encryptor -d -f document.pdf.enc -p myStrongPassword123
101117
```
102118

103119
---
@@ -126,4 +142,3 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
126142
This tool is provided as-is, without any warranties. Always ensure you have backups of your important files before encryption.
127143

128144
---
129-

cmd/file-encryptor/main.go

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,23 @@ import (
1313

1414
func main() {
1515
logger := logging.NewLogger()
16+
logger.LogDebug("Starting file encryptor")
1617

1718
encrypt := flag.Bool("e", false, "Encrypt the file")
1819
decrypt := flag.Bool("d", false, "Decrypt the file")
20+
21+
// Define both short and long flag names for file and key
1922
file := flag.String("file", "", "File to encrypt or decrypt")
20-
key := flag.String("key", "", "Path to the key file (public key for encryption, private key for decryption)")
23+
flag.StringVar(file, "f", "", "File to encrypt or decrypt (shorthand)") //Bind short flag to the same variable
24+
key := flag.String("key", "", "Path to the key file")
25+
flag.StringVar(key, "k", "", "Path to the key file (shorthand)") //Bind short flag to the same variable
26+
2127
password := flag.String("password", "", "Password for encryption/decryption (alternative to key file)")
28+
flag.StringVar(password, "p", "", "Password for encryption/decryption (shorthand)") //Bind short flag to the same variable
2229
flag.Parse()
30+
logger.LogDebug("Parsed command line flags")
2331

32+
// Use the flag values after parsing.
2433
if err := validateFlags(*encrypt, *decrypt, *file, *key, *password); err != nil {
2534
logger.LogError(err.Error())
2635
flag.Usage()
@@ -36,16 +45,18 @@ func main() {
3645
operation = "Decryption"
3746
outputFile, err = handleDecryption(*file, *key, *password, logger)
3847
}
48+
logger.LogDebugf("Operation: %s, Output file: %s", operation, outputFile)
3949

4050
if err != nil {
4151
logger.LogError(fmt.Sprintf("%v", err))
4252
if os.IsNotExist(err) {
43-
logger.Log("Please check if the specified file and key exist and are readable.")
53+
logger.LogInfo("Please check if the specified file and key exist and are readable.")
4454
}
4555
os.Exit(1)
4656
}
4757

48-
logger.Log(fmt.Sprintf("File %s completed. Output file: %s", strings.ToLower(operation), outputFile))
58+
logger.LogInfo(fmt.Sprintf("File %s completed. Output file: %s", strings.ToLower(operation), outputFile))
59+
logger.LogDebug("File encryption/decryption completed")
4960
}
5061

5162
func validateFlags(encrypt, decrypt bool, file, key, password string) error {
@@ -54,22 +65,22 @@ func validateFlags(encrypt, decrypt bool, file, key, password string) error {
5465
}
5566

5667
if file == "" {
57-
return fmt.Errorf("please provide the --file argument")
68+
return fmt.Errorf("please provide the --file or -f argument")
5869
}
5970

6071
if key == "" && password == "" {
61-
return fmt.Errorf("please provide either --key or --password argument")
72+
return fmt.Errorf("please provide either --key or -k or --password or -p argument")
6273
}
6374

6475
if key != "" && password != "" {
65-
return fmt.Errorf("please provide either --key or --password, not both")
76+
return fmt.Errorf("please provide either --key or -k or --password or -p, not both")
6677
}
6778

6879
return nil
6980
}
7081

7182
func handleEncryption(file, key, password string, logger *logging.Logger) (string, error) {
72-
logger.Log("Starting file encryption")
83+
logger.LogInfo("Starting file encryption")
7384
var encryptor crypto.Encryptor
7485
var err error
7586

@@ -78,6 +89,7 @@ func handleEncryption(file, key, password string, logger *logging.Logger) (strin
7889
} else {
7990
encryptor, err = crypto.NewPasswordEncryptor(password)
8091
}
92+
logger.LogDebugf("Initialized encryptor: %T", encryptor)
8193

8294
if err != nil {
8395
return "", fmt.Errorf("error initializing encryptor: %v", err)
@@ -89,7 +101,7 @@ func handleEncryption(file, key, password string, logger *logging.Logger) (strin
89101
}
90102

91103
func handleDecryption(file, key, password string, logger *logging.Logger) (string, error) {
92-
logger.Log("Starting file decryption")
104+
logger.LogInfo("Starting file decryption")
93105
var decryptor crypto.Decryptor
94106
var err error
95107

@@ -98,6 +110,7 @@ func handleDecryption(file, key, password string, logger *logging.Logger) (strin
98110
} else {
99111
decryptor, err = crypto.NewPasswordDecryptor(password)
100112
}
113+
logger.LogDebugf("Initialized decryptor: %T", decryptor)
101114

102115
if err != nil {
103116
return "", fmt.Errorf("error initializing decryptor: %v", err)

pkg/crypto/aes.go

Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,55 @@
11
package crypto
22

33
import (
4-
"crypto/aes"
5-
"crypto/cipher"
6-
"crypto/rand"
7-
"io"
4+
"crypto/aes"
5+
"crypto/cipher"
6+
"crypto/rand"
7+
"fmt"
8+
"io"
89
)
910

1011
func EncryptAES(plaintext, key []byte) ([]byte, error) {
11-
block, err := aes.NewCipher(key)
12-
if err != nil {
13-
return nil, err
14-
}
12+
if len(key) != 32 {
13+
return nil, fmt.Errorf("invalid key size: expected 32 bytes, got %d", len(key))
14+
}
1515

16-
ciphertext := make([]byte, aes.BlockSize+len(plaintext))
17-
iv := ciphertext[:aes.BlockSize]
18-
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
19-
return nil, err
20-
}
16+
block, err := aes.NewCipher(key)
17+
if err != nil {
18+
return nil, fmt.Errorf("failed to create cipher: %v", err)
19+
}
2120

22-
stream := cipher.NewCFBEncrypter(block, iv)
23-
stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext)
21+
ciphertext := make([]byte, aes.BlockSize+len(plaintext))
22+
iv := ciphertext[:aes.BlockSize]
23+
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
24+
return nil, fmt.Errorf("failed to generate IV: %v", err)
25+
}
2426

25-
return ciphertext, nil
27+
stream := cipher.NewCFBEncrypter(block, iv)
28+
stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext)
29+
30+
return ciphertext, nil
2631
}
2732

2833
func DecryptAES(ciphertext, key []byte) ([]byte, error) {
29-
block, err := aes.NewCipher(key)
30-
if err != nil {
31-
return nil, err
32-
}
33-
34-
if len(ciphertext) < aes.BlockSize {
35-
return nil, err
36-
}
37-
iv := ciphertext[:aes.BlockSize]
38-
ciphertext = ciphertext[aes.BlockSize:]
39-
40-
stream := cipher.NewCFBDecrypter(block, iv)
41-
stream.XORKeyStream(ciphertext, ciphertext)
42-
43-
return ciphertext, nil
44-
}
34+
if len(key) != 32 {
35+
return nil, fmt.Errorf("invalid key size: expected 32 bytes, got %d", len(key))
36+
}
37+
38+
block, err := aes.NewCipher(key)
39+
if err != nil {
40+
return nil, fmt.Errorf("failed to create cipher: %v", err)
41+
}
42+
43+
if len(ciphertext) < aes.BlockSize {
44+
return nil, fmt.Errorf("ciphertext too short")
45+
}
46+
47+
iv := ciphertext[:aes.BlockSize]
48+
ciphertext = ciphertext[aes.BlockSize:]
49+
50+
stream := cipher.NewCFBDecrypter(block, iv)
51+
plaintext := make([]byte, len(ciphertext))
52+
stream.XORKeyStream(plaintext, ciphertext)
53+
54+
return plaintext, nil
55+
}

pkg/fileops/fileops.go

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,14 @@ import (
1212
"io"
1313
"os"
1414
"path/filepath"
15+
"strings"
1516
"time"
1617
)
1718

1819
const chunkSize = 64 * 1024 // 64KB chunks
1920

2021
func EncryptFile(inputFile, outputFile string, encryptor crypto.Encryptor, logger *logging.Logger) error {
21-
logger.Log(fmt.Sprintf("Starting encryption of file: %s", inputFile))
22+
logger.LogInfo(fmt.Sprintf("Starting encryption of file: %s", inputFile))
2223
startTime := time.Now()
2324

2425
inFile, err := os.Open(inputFile)
@@ -73,12 +74,12 @@ func EncryptFile(inputFile, outputFile string, encryptor crypto.Encryptor, logge
7374
return err
7475
}
7576

76-
logger.Log(fmt.Sprintf("Encryption completed in %v", time.Since(startTime)))
77+
logger.LogInfof("Encryption completed in %v", time.Since(startTime))
7778
return nil
7879
}
7980

8081
func DecryptFile(inputFile, outputFile string, decryptor crypto.Decryptor, logger *logging.Logger) error {
81-
logger.Log(fmt.Sprintf("Starting decryption of file: %s", inputFile))
82+
logger.LogInfo(fmt.Sprintf("Starting decryption of file: %s", inputFile))
8283
startTime := time.Now()
8384

8485
inFile, err := os.Open(inputFile)
@@ -94,7 +95,10 @@ func DecryptFile(inputFile, outputFile string, decryptor crypto.Decryptor, logge
9495
if err != nil {
9596
return err
9697
}
97-
outputFile += extension
98+
// FIX: Construct outputFile correctly to avoid double extension
99+
outputFile = strings.TrimSuffix(outputFile, filepath.Ext(outputFile)) // Remove existing extension (if any)
100+
outputFile += extension
101+
98102

99103
outFile, err := os.Create(outputFile)
100104
if err != nil {
@@ -125,7 +129,7 @@ func DecryptFile(inputFile, outputFile string, decryptor crypto.Decryptor, logge
125129
return err
126130
}
127131

128-
logger.Log(fmt.Sprintf("Decryption completed in %v", time.Since(startTime)))
132+
logger.LogInfof("Decryption completed in %v", time.Since(startTime))
129133
return nil
130134
}
131135

@@ -167,21 +171,22 @@ func readLengthAndData(r *bufio.Reader) ([]byte, error) {
167171

168172
func processFileContent(r *bufio.Reader, w *bufio.Writer, stream cipher.Stream) error {
169173
buf := make([]byte, chunkSize)
174+
outBuf := make([]byte, chunkSize)
175+
170176
for {
171177
n, err := r.Read(buf)
172178
if n > 0 {
173-
encrypted := make([]byte, n)
174-
stream.XORKeyStream(encrypted, buf[:n])
175-
if _, err := w.Write(encrypted); err != nil {
176-
return err
179+
stream.XORKeyStream(outBuf[:n], buf[:n])
180+
if _, err := w.Write(outBuf[:n]); err != nil {
181+
return fmt.Errorf("write error: %v", err)
177182
}
178183
}
179184
if err == io.EOF {
180185
break
181186
}
182187
if err != nil {
183-
return err
188+
return fmt.Errorf("read error: %v", err)
184189
}
185190
}
186-
return nil
191+
return w.Flush()
187192
}

0 commit comments

Comments
 (0)