From 9c1928979094ca6c7b2c742bd702038744b99a92 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Fri, 13 Jun 2025 08:35:22 +0200 Subject: [PATCH 1/2] Helper to create a file with encrypted content --- encrypt.go | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 encrypt.go diff --git a/encrypt.go b/encrypt.go new file mode 100644 index 0000000..b25b8bb --- /dev/null +++ b/encrypt.go @@ -0,0 +1,58 @@ +package main + +import ( + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "encoding/hex" + "fmt" + "io" + "os" +) + +func main() { + var data string + fmt.Print("Enter the data to encrypt: ") + fmt.Scanln(&data) + plaintext := []byte(data) + + var key string + fmt.Print("Enter a 32-byte encryption key: ") + fmt.Scanln(&key) + + // Convert the key to a byte slice + keyBytes := []byte(key) + if len(keyBytes) != 32 { + fmt.Println("Key must be 32 bytes long for AES-256") + return + } + + block, err := aes.NewCipher(keyBytes) + if err != nil { + fmt.Println("Error creating AES block cipher", err) + return + } + + gcm, err := cipher.NewGCM(block) + if err != nil { + fmt.Println("Error setting GCM mode", err) + return + } + + nonce := make([]byte, gcm.NonceSize()) + if _, err := io.ReadFull(rand.Reader, nonce); err != nil { + fmt.Println("Error generating the nonce ", err) + return + } + + ciphertext := gcm.Seal(nonce, nonce, plaintext, nil) + + enc := hex.EncodeToString(ciphertext) + fmt.Println("Encrypted data:", enc) + err = os.WriteFile("secret.enc", []byte(enc), 0600) + if err != nil { + fmt.Println("Error writing to file:", err) + return + } + fmt.Println("Encrypted data written to secret.enc") +} \ No newline at end of file From 7e45223caa307610716fcae49bfeb2953707b9b2 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Fri, 13 Jun 2025 08:36:49 +0200 Subject: [PATCH 2/2] Add support to read a password from an encrypted file --- cmd/auth/config/configuration.go | 92 +++++++++++++++++++++++++++----- go.mod | 5 +- 2 files changed, 82 insertions(+), 15 deletions(-) diff --git a/cmd/auth/config/configuration.go b/cmd/auth/config/configuration.go index 580b7f2..67b8c11 100644 --- a/cmd/auth/config/configuration.go +++ b/cmd/auth/config/configuration.go @@ -5,6 +5,10 @@ import ( "github.com/knadh/koanf/providers/confmap" "github.com/knadh/koanf/providers/file" "github.com/knadh/koanf/v2" + "crypto/aes" + "crypto/cipher" + "encoding/hex" + "io/ioutil" "log" "os" ) @@ -14,29 +18,91 @@ type Configuration struct { } type UserConfig struct { - Username string `koanf:"username"` - Password string `koanf:"password"` + Username string `koanf:"username"` + Password string `koanf:"password"` + Path string `koanf:"path"` } var Conf Configuration func Load(configFile string) Configuration { - var k = koanf.New(".") + var k = koanf.New(".") - k.Load(confmap.Provider(map[string]interface{}{}, "."), nil) + k.Load(confmap.Provider(map[string]interface{}{}, "."), nil) - if _, err := os.Stat(configFile); os.IsNotExist(err) { - log.Printf("Config file %s not found, skipping config file", configFile) - } else { - if err := k.Load(file.Provider(configFile), yaml.Parser()); err != nil { - log.Fatalf("Error loading config from file: %v", err) - } + if _, err := os.Stat(configFile); os.IsNotExist(err) { + log.Printf("Config file %s not found, skipping config file", configFile) + } else { + if err := k.Load(file.Provider(configFile), yaml.Parser()); err != nil { + log.Fatalf("Error loading config from file: %v", err) + } + } + + koanfTag := koanf.UnmarshalConf{Tag: "koanf"} + k.UnmarshalWithConf("Users", &Conf.Users, koanfTag) + + var password, path string + if len(Conf.Users) > 0 { + password = Conf.Users[0].Password + path = Conf.Users[0].Path + // log.Printf("Password from Conf: %s", password) + // log.Printf("Path from Conf: %s", path) + + decrypted, err := DecryptFileContent(path, password) + if err != nil { + log.Printf("Failed to decrypt file: %v", err) + } else { + // log.Printf("Decrypted file content: %s", decrypted) + Conf.Users[0].Password = decrypted + } + } else { + log.Printf("No users found in configuration") + } + + // Log the loaded configuration to the console + // log.Printf("Loaded configuration: %+v", Conf) + + return Conf +} + +func DecryptFileContent(path, passphrase string) (string, error) { + encryptedData, err := ioutil.ReadFile(path) + if err != nil { + return "", err + } + // log.Printf("Loaded secret: %s", encryptedData) + // log.Printf("Encryption key: %s", passphrase) + + keyBytes := []byte(passphrase) + if len(keyBytes) != 32 { + log.Printf("Key must be 32 bytes long for AES-256: %d bytes provided", len(keyBytes)) + return "", err + } + + block, err := aes.NewCipher(keyBytes) + if err != nil { + log.Printf("Error creating AES block cipher: %s", err) + return "", err } - koanfTag := koanf.UnmarshalConf{Tag: "koanf"} - k.UnmarshalWithConf("Users", &Conf.Users, koanfTag) + gcm, err := cipher.NewGCM(block) + if err != nil { + log.Printf("Error setting GCM mode: %s", err) + return "", err + } - return Conf + decodedCipherText, err := hex.DecodeString(string(encryptedData)) + if err != nil { + log.Printf("Error decoding HEX: %s", err) + return "", err + } + + decryptedData, err := gcm.Open(nil, decodedCipherText[:gcm.NonceSize()], decodedCipherText[gcm.NonceSize():], nil) + if err != nil { + log.Printf("Error decrypting data: %s", err) + return "", err + } + return string(decryptedData), nil } diff --git a/go.mod b/go.mod index bc7ec07..217df41 100644 --- a/go.mod +++ b/go.mod @@ -1,7 +1,8 @@ module github.com/bolkedebruin/rdpgw -go 1.22 -toolchain go1.24.1 +go 1.23.0 + +toolchain go1.24.3 require ( github.com/bolkedebruin/gokrb5/v8 v8.5.0