From 7173064451a0c7372be37b2d4914b07d6ee5dfda Mon Sep 17 00:00:00 2001 From: Marvin Gajek Date: Wed, 13 Nov 2024 17:56:42 +0100 Subject: [PATCH 1/6] move functions --- cmd/crypto-vault-cli/crypto-vault-cli.go | 329 +----------------- .../internal/commands/aes-commands.go | 97 ++++++ .../internal/commands/ecdsa-commands.go | 129 +++++++ .../internal/commands/rsa-commands.go | 117 +++++++ 4 files changed, 351 insertions(+), 321 deletions(-) create mode 100644 cmd/crypto-vault-cli/internal/commands/aes-commands.go create mode 100644 cmd/crypto-vault-cli/internal/commands/ecdsa-commands.go create mode 100644 cmd/crypto-vault-cli/internal/commands/rsa-commands.go diff --git a/cmd/crypto-vault-cli/crypto-vault-cli.go b/cmd/crypto-vault-cli/crypto-vault-cli.go index 7ac8cab..e346443 100644 --- a/cmd/crypto-vault-cli/crypto-vault-cli.go +++ b/cmd/crypto-vault-cli/crypto-vault-cli.go @@ -1,327 +1,14 @@ package main import ( - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rsa" - "encoding/hex" "fmt" - "log" "os" - "path/filepath" - "github.com/spf13/cobra" + commands "crypto_vault_service/cmd/crypto-vault-cli/internal/commands" - cryptography "crypto_vault_service/internal/infrastructure/cryptography" - utils "crypto_vault_service/internal/infrastructure/utils" + "github.com/spf13/cobra" ) -// Encrypts a file using AES and saves the encryption key -func encryptAESCmd(cmd *cobra.Command, args []string) { - inputFile, _ := cmd.Flags().GetString("input") - outputFile, _ := cmd.Flags().GetString("output") - keySize, _ := cmd.Flags().GetInt("keySize") - keyDir, _ := cmd.Flags().GetString("keyDir") - - // Validate input arguments - if inputFile == "" || outputFile == "" || keyDir == "" { - log.Fatalf("Error: input, output, and keyDir flags are required\n") - } - - aes := &cryptography.AESImpl{} - - // Generate AES Key - key, err := aes.GenerateKey(keySize) - if err != nil { - log.Fatalf("Error generating AES key: %v\n", err) - } - - // Encrypt the file - plainText, err := utils.ReadFile(inputFile) - if err != nil { - log.Fatalf("Error reading input file: %v\n", err) - } - - encryptedData, err := aes.Encrypt(plainText, key) - if err != nil { - log.Fatalf("Error encrypting data: %v\n", err) - } - - // Save encrypted file - err = utils.WriteFile(outputFile, encryptedData) - if err != nil { - log.Fatalf("Error writing encrypted file: %v\n", err) - } - fmt.Printf("Encrypted data saved to %s\n", outputFile) - - // Save the AES key to the specified key directory - keyFilePath := filepath.Join(keyDir, "encryption_key.bin") - err = utils.WriteFile(keyFilePath, key) - if err != nil { - log.Fatalf("Error writing AES key to file: %v\n", err) - } - fmt.Printf("AES key saved to %s\n", keyFilePath) -} - -func decryptAESCmd(cmd *cobra.Command, args []string) { - inputFile, _ := cmd.Flags().GetString("input") - outputFile, _ := cmd.Flags().GetString("output") - keyDir, _ := cmd.Flags().GetString("keyDir") - - // Validate input arguments - if inputFile == "" || outputFile == "" || keyDir == "" { - log.Fatalf("Error: input, output, and keyDir flags are required\n") - } - - // Read the encryption key from the specified directory - keyFilePath := filepath.Join(keyDir, "encryption_key.bin") - key, err := os.ReadFile(keyFilePath) - if err != nil { - log.Fatalf("Error reading encryption key from file: %v\n", err) - } - - // Decrypt the file - encryptedData, err := utils.ReadFile(inputFile) - if err != nil { - log.Fatalf("Error reading encrypted file: %v\n", err) - } - - aes := &cryptography.AESImpl{} - - decryptedData, err := aes.Decrypt(encryptedData, key) - if err != nil { - log.Fatalf("Error decrypting data: %v\n", err) - } - - // Save decrypted file - err = utils.WriteFile(outputFile, decryptedData) - if err != nil { - log.Fatalf("Error writing decrypted file: %v\n", err) - } - fmt.Printf("Decrypted data saved to %s\n", outputFile) -} - -// RSA Command -func encryptRSACmd(cmd *cobra.Command, args []string) { - inputFile, _ := cmd.Flags().GetString("input") - outputFile, _ := cmd.Flags().GetString("output") - publicKeyPath, _ := cmd.Flags().GetString("publicKey") - - // Generate RSA keys if no public key is provided - var publicKey *rsa.PublicKey - var err error - rsa := &cryptography.RSAImpl{} - if publicKeyPath == "" { - // Generate RSA keys - - privateKey, pubKey, genErr := rsa.GenerateKeys(2048) - if genErr != nil { - log.Fatalf("Error generating RSA keys: %v\n", genErr) - } - publicKey = pubKey - - // Optionally save the private and public keys - err = rsa.SavePrivateKeyToFile(privateKey, "data/private_key.pem") - if err != nil { - log.Fatalf("Error saving private key: %v\n", err) - } - err = rsa.SavePublicKeyToFile(publicKey, "data/public_key.pem") - if err != nil { - log.Fatalf("Error saving public key: %v\n", err) - } - fmt.Println("Generated and saved RSA keys.") - } else { - // Read the provided public key - publicKey, err = rsa.ReadPublicKey(publicKeyPath) - if err != nil { - log.Fatalf("Error reading public key: %v\n", err) - } - } - - // Encrypt the file - plainText, err := utils.ReadFile(inputFile) - if err != nil { - log.Fatalf("Error reading input file: %v\n", err) - } - - encryptedData, err := rsa.Encrypt(plainText, publicKey) - if err != nil { - log.Fatalf("Error encrypting data: %v\n", err) - } - - // Save encrypted file - err = utils.WriteFile(outputFile, encryptedData) - if err != nil { - log.Fatalf("Error writing encrypted file: %v\n", err) - } - fmt.Printf("Encrypted data saved to %s\n", outputFile) -} - -func decryptRSACmd(cmd *cobra.Command, args []string) { - inputFile, _ := cmd.Flags().GetString("input") - outputFile, _ := cmd.Flags().GetString("output") - privateKeyPath, _ := cmd.Flags().GetString("privateKey") - - // Generate RSA keys if no private key is provided - var privateKey *rsa.PrivateKey - var err error - rsa := &cryptography.RSAImpl{} - if privateKeyPath == "" { - // Generate RSA keys - privKey, _, genErr := rsa.GenerateKeys(2048) - if genErr != nil { - log.Fatalf("Error generating RSA keys: %v\n", genErr) - } - privateKey = privKey - - // Optionally save the private and public keys - err = rsa.SavePrivateKeyToFile(privateKey, "private_key.pem") - if err != nil { - log.Fatalf("Error saving private key: %v\n", err) - } - fmt.Println("Generated and saved private key.") - } else { - // Read the provided private key - privateKey, err = rsa.ReadPrivateKey(privateKeyPath) - if err != nil { - log.Fatalf("Error reading private key: %v\n", err) - } - } - - // Decrypt the file - encryptedData, err := utils.ReadFile(inputFile) - if err != nil { - log.Fatalf("Error reading encrypted file: %v\n", err) - } - - decryptedData, err := rsa.Decrypt(encryptedData, privateKey) - if err != nil { - log.Fatalf("Error decrypting data: %v\n", err) - } - - // Save decrypted file - err = utils.WriteFile(outputFile, decryptedData) - if err != nil { - log.Fatalf("Error writing decrypted file: %v\n", err) - } - fmt.Printf("Decrypted data saved to %s\n", outputFile) -} - -// ECDSA command -// signECCCmd signs the contents of a file with ECDSA -func signECCCmd(cmd *cobra.Command, args []string) { - inputFile, _ := cmd.Flags().GetString("input") // File to sign - keyDir, _ := cmd.Flags().GetString("keyDir") // Directory to save keys - - // ECC implementation - ecdsaImpl := &cryptography.ECDSAImpl{} - var privateKey *ecdsa.PrivateKey - var publicKey *ecdsa.PublicKey - var err error - - // Generate new ECC keys if no private key is provided - privateKey, publicKey, err = ecdsaImpl.GenerateKeys(elliptic.P256()) - if err != nil { - log.Fatalf("Error generating ECC keys: %v\n", err) - } - - // Read the file content - fileContent, err := utils.ReadFile(inputFile) - if err != nil { - log.Fatalf("Error reading input file: %v\n", err) - } - - // Sign the file content (hash the content before signing) - signature, err := ecdsaImpl.Sign(fileContent, privateKey) - if err != nil { - log.Fatalf("Error signing file content: %v\n", err) - } - - // Output the signature - fmt.Printf("Signature: %x\n", signature) - - // Save the private and public keys to files (if they were generated) - if privateKey != nil && keyDir != "" { - privateKeyFilePath := fmt.Sprintf("%s/private_key.pem", keyDir) - err = ecdsaImpl.SavePrivateKeyToFile(privateKey, privateKeyFilePath) - if err != nil { - log.Fatalf("Error saving private key: %v\n", err) - } - fmt.Printf("Private key saved to: %s\n", privateKeyFilePath) - } - - if publicKey != nil && keyDir != "" { - publicKeyFilePath := fmt.Sprintf("%s/public_key.pem", keyDir) - err = ecdsaImpl.SavePublicKeyToFile(publicKey, publicKeyFilePath) - if err != nil { - log.Fatalf("Error saving public key: %v\n", err) - } - fmt.Printf("Public key saved to: %s\n", publicKeyFilePath) - } - - // Save the signature to a file in the data folder (optional, based on the input file) - if keyDir != "" { - signatureFilePath := fmt.Sprintf("%s/signature.sig", keyDir) - err = ecdsaImpl.SaveSignatureToFile(signatureFilePath, signature) - if err != nil { - log.Fatalf("Error saving signature: %v\n", err) - } - fmt.Printf("Signature saved to: %s\n", signatureFilePath) - } -} - -// verifyECCCmd verifies the signature of a file's content using ECDSA -func verifyECCCmd(cmd *cobra.Command, args []string) { - publicKeyPath, _ := cmd.Flags().GetString("publicKey") // Path to public key - inputFile, _ := cmd.Flags().GetString("input") // Input file to verify - signatureFile, _ := cmd.Flags().GetString("signature") // Path to signature file - - // ECC implementation - ecdsaImpl := &cryptography.ECDSAImpl{} - var publicKey *ecdsa.PublicKey - var err error - - // Read the public key - if publicKeyPath == "" { - log.Fatalf("Public key is required for ECC signature verification.\n") - } else { - publicKey, err = ecdsaImpl.ReadPublicKey(publicKeyPath) - if err != nil { - log.Fatalf("Error reading public key: %v\n", err) - } - } - - // Read the file content (optional: you can also hash the content before verifying) - fileContent, err := utils.ReadFile(inputFile) - if err != nil { - log.Fatalf("Error reading input file: %v\n", err) - } - - // Read the signature (from hex file) - signatureHex, err := os.ReadFile(signatureFile) - if err != nil { - log.Fatalf("Error reading signature file: %v\n", err) - } - - // Decode the hex string back to bytes - signature, err := hex.DecodeString(string(signatureHex)) - if err != nil { - log.Fatalf("Error decoding signature hex: %v\n", err) - } - - // Verify the signature - valid, err := ecdsaImpl.Verify(fileContent, signature, publicKey) - if err != nil { - log.Fatalf("Error verifying signature: %v\n", err) - } - - if valid { - fmt.Println("Signature is valid.") - } else { - fmt.Println("Signature is invalid.") - } -} - // Main function func main() { var rootCmd = &cobra.Command{Use: "crypto-cli"} @@ -330,7 +17,7 @@ func main() { var encryptAESFileCmd = &cobra.Command{ Use: "encrypt-aes", Short: "Encrypt a file using AES", - Run: encryptAESCmd, + Run: commands.EncryptAESCmd, } encryptAESFileCmd.Flags().StringP("input", "i", "", "Input file path") encryptAESFileCmd.Flags().StringP("output", "o", "", "Output encrypted file path") @@ -341,7 +28,7 @@ func main() { var decryptAESFileCmd = &cobra.Command{ Use: "decrypt-aes", Short: "Decrypt a file using AES", - Run: decryptAESCmd, + Run: commands.DecryptAESCmd, } decryptAESFileCmd.Flags().StringP("input", "i", "", "Input encrypted file path") decryptAESFileCmd.Flags().StringP("output", "o", "", "Output decrypted file path") @@ -352,7 +39,7 @@ func main() { var encryptRSAFileCmd = &cobra.Command{ Use: "encrypt-rsa", Short: "Encrypt a file using RSA", - Run: encryptRSACmd, + Run: commands.EncryptRSACmd, } encryptRSAFileCmd.Flags().StringP("input", "i", "", "Input file path") encryptRSAFileCmd.Flags().StringP("output", "o", "", "Output encrypted file path") @@ -362,7 +49,7 @@ func main() { var decryptRSAFileCmd = &cobra.Command{ Use: "decrypt-rsa", Short: "Decrypt a file using RSA", - Run: decryptRSACmd, + Run: commands.DecryptRSACmd, } decryptRSAFileCmd.Flags().StringP("input", "i", "", "Input encrypted file path") decryptRSAFileCmd.Flags().StringP("output", "o", "", "Output decrypted file path") @@ -373,7 +60,7 @@ func main() { var signECCMessageCmd = &cobra.Command{ Use: "sign-ecc", Short: "Sign a message using ECC", - Run: signECCCmd, + Run: commands.SignECCCmd, } // Rename the input flag to messageFile for clarity @@ -384,7 +71,7 @@ func main() { var verifyECCSignatureCmd = &cobra.Command{ Use: "verify-ecc", Short: "Verify a signature using ECC", - Run: verifyECCCmd, + Run: commands.VerifyECCCmd, } verifyECCSignatureCmd.Flags().StringP("input", "i", "", "Path to ECC public key") verifyECCSignatureCmd.Flags().StringP("publicKey", "p", "", "The public key used to verify the signature") diff --git a/cmd/crypto-vault-cli/internal/commands/aes-commands.go b/cmd/crypto-vault-cli/internal/commands/aes-commands.go new file mode 100644 index 0000000..b4dc16e --- /dev/null +++ b/cmd/crypto-vault-cli/internal/commands/aes-commands.go @@ -0,0 +1,97 @@ +package commands + +import ( + "crypto_vault_service/internal/infrastructure/cryptography" + "crypto_vault_service/internal/infrastructure/utils" + "fmt" + "log" + "os" + "path/filepath" + + "github.com/spf13/cobra" +) + +// Encrypts a file using AES and saves the encryption key +func EncryptAESCmd(cmd *cobra.Command, args []string) { + inputFile, _ := cmd.Flags().GetString("input") + outputFile, _ := cmd.Flags().GetString("output") + keySize, _ := cmd.Flags().GetInt("keySize") + keyDir, _ := cmd.Flags().GetString("keyDir") + + // Validate input arguments + if inputFile == "" || outputFile == "" || keyDir == "" { + log.Fatalf("Error: input, output, and keyDir flags are required\n") + } + + aes := &cryptography.AESImpl{} + + // Generate AES Key + key, err := aes.GenerateKey(keySize) + if err != nil { + log.Fatalf("Error generating AES key: %v\n", err) + } + + // Encrypt the file + plainText, err := utils.ReadFile(inputFile) + if err != nil { + log.Fatalf("Error reading input file: %v\n", err) + } + + encryptedData, err := aes.Encrypt(plainText, key) + if err != nil { + log.Fatalf("Error encrypting data: %v\n", err) + } + + // Save encrypted file + err = utils.WriteFile(outputFile, encryptedData) + if err != nil { + log.Fatalf("Error writing encrypted file: %v\n", err) + } + fmt.Printf("Encrypted data saved to %s\n", outputFile) + + // Save the AES key to the specified key directory + keyFilePath := filepath.Join(keyDir, "encryption_key.bin") + err = utils.WriteFile(keyFilePath, key) + if err != nil { + log.Fatalf("Error writing AES key to file: %v\n", err) + } + fmt.Printf("AES key saved to %s\n", keyFilePath) +} + +func DecryptAESCmd(cmd *cobra.Command, args []string) { + inputFile, _ := cmd.Flags().GetString("input") + outputFile, _ := cmd.Flags().GetString("output") + keyDir, _ := cmd.Flags().GetString("keyDir") + + // Validate input arguments + if inputFile == "" || outputFile == "" || keyDir == "" { + log.Fatalf("Error: input, output, and keyDir flags are required\n") + } + + // Read the encryption key from the specified directory + keyFilePath := filepath.Join(keyDir, "encryption_key.bin") + key, err := os.ReadFile(keyFilePath) + if err != nil { + log.Fatalf("Error reading encryption key from file: %v\n", err) + } + + // Decrypt the file + encryptedData, err := utils.ReadFile(inputFile) + if err != nil { + log.Fatalf("Error reading encrypted file: %v\n", err) + } + + aes := &cryptography.AESImpl{} + + decryptedData, err := aes.Decrypt(encryptedData, key) + if err != nil { + log.Fatalf("Error decrypting data: %v\n", err) + } + + // Save decrypted file + err = utils.WriteFile(outputFile, decryptedData) + if err != nil { + log.Fatalf("Error writing decrypted file: %v\n", err) + } + fmt.Printf("Decrypted data saved to %s\n", outputFile) +} diff --git a/cmd/crypto-vault-cli/internal/commands/ecdsa-commands.go b/cmd/crypto-vault-cli/internal/commands/ecdsa-commands.go new file mode 100644 index 0000000..5257d92 --- /dev/null +++ b/cmd/crypto-vault-cli/internal/commands/ecdsa-commands.go @@ -0,0 +1,129 @@ +package commands + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto_vault_service/internal/infrastructure/cryptography" + "crypto_vault_service/internal/infrastructure/utils" + "encoding/hex" + "fmt" + "log" + "os" + + "github.com/spf13/cobra" +) + +// ECDSA command +// signECCCmd signs the contents of a file with ECDSA +func SignECCCmd(cmd *cobra.Command, args []string) { + inputFile, _ := cmd.Flags().GetString("input") // File to sign + keyDir, _ := cmd.Flags().GetString("keyDir") // Directory to save keys + + // ECC implementation + ecdsaImpl := &cryptography.ECDSAImpl{} + var privateKey *ecdsa.PrivateKey + var publicKey *ecdsa.PublicKey + var err error + + // Generate new ECC keys if no private key is provided + privateKey, publicKey, err = ecdsaImpl.GenerateKeys(elliptic.P256()) + if err != nil { + log.Fatalf("Error generating ECC keys: %v\n", err) + } + + // Read the file content + fileContent, err := utils.ReadFile(inputFile) + if err != nil { + log.Fatalf("Error reading input file: %v\n", err) + } + + // Sign the file content (hash the content before signing) + signature, err := ecdsaImpl.Sign(fileContent, privateKey) + if err != nil { + log.Fatalf("Error signing file content: %v\n", err) + } + + // Output the signature + fmt.Printf("Signature: %x\n", signature) + + // Save the private and public keys to files (if they were generated) + if privateKey != nil && keyDir != "" { + privateKeyFilePath := fmt.Sprintf("%s/private_key.pem", keyDir) + err = ecdsaImpl.SavePrivateKeyToFile(privateKey, privateKeyFilePath) + if err != nil { + log.Fatalf("Error saving private key: %v\n", err) + } + fmt.Printf("Private key saved to: %s\n", privateKeyFilePath) + } + + if publicKey != nil && keyDir != "" { + publicKeyFilePath := fmt.Sprintf("%s/public_key.pem", keyDir) + err = ecdsaImpl.SavePublicKeyToFile(publicKey, publicKeyFilePath) + if err != nil { + log.Fatalf("Error saving public key: %v\n", err) + } + fmt.Printf("Public key saved to: %s\n", publicKeyFilePath) + } + + // Save the signature to a file in the data folder (optional, based on the input file) + if keyDir != "" { + signatureFilePath := fmt.Sprintf("%s/signature.sig", keyDir) + err = ecdsaImpl.SaveSignatureToFile(signatureFilePath, signature) + if err != nil { + log.Fatalf("Error saving signature: %v\n", err) + } + fmt.Printf("Signature saved to: %s\n", signatureFilePath) + } +} + +// verifyECCCmd verifies the signature of a file's content using ECDSA +func VerifyECCCmd(cmd *cobra.Command, args []string) { + publicKeyPath, _ := cmd.Flags().GetString("publicKey") // Path to public key + inputFile, _ := cmd.Flags().GetString("input") // Input file to verify + signatureFile, _ := cmd.Flags().GetString("signature") // Path to signature file + + // ECC implementation + ecdsaImpl := &cryptography.ECDSAImpl{} + var publicKey *ecdsa.PublicKey + var err error + + // Read the public key + if publicKeyPath == "" { + log.Fatalf("Public key is required for ECC signature verification.\n") + } else { + publicKey, err = ecdsaImpl.ReadPublicKey(publicKeyPath) + if err != nil { + log.Fatalf("Error reading public key: %v\n", err) + } + } + + // Read the file content (optional: you can also hash the content before verifying) + fileContent, err := utils.ReadFile(inputFile) + if err != nil { + log.Fatalf("Error reading input file: %v\n", err) + } + + // Read the signature (from hex file) + signatureHex, err := os.ReadFile(signatureFile) + if err != nil { + log.Fatalf("Error reading signature file: %v\n", err) + } + + // Decode the hex string back to bytes + signature, err := hex.DecodeString(string(signatureHex)) + if err != nil { + log.Fatalf("Error decoding signature hex: %v\n", err) + } + + // Verify the signature + valid, err := ecdsaImpl.Verify(fileContent, signature, publicKey) + if err != nil { + log.Fatalf("Error verifying signature: %v\n", err) + } + + if valid { + fmt.Println("Signature is valid.") + } else { + fmt.Println("Signature is invalid.") + } +} diff --git a/cmd/crypto-vault-cli/internal/commands/rsa-commands.go b/cmd/crypto-vault-cli/internal/commands/rsa-commands.go new file mode 100644 index 0000000..2093969 --- /dev/null +++ b/cmd/crypto-vault-cli/internal/commands/rsa-commands.go @@ -0,0 +1,117 @@ +package commands + +import ( + "crypto/rsa" + "crypto_vault_service/internal/infrastructure/cryptography" + "crypto_vault_service/internal/infrastructure/utils" + "fmt" + "log" + + "github.com/spf13/cobra" +) + +// RSA Command +func EncryptRSACmd(cmd *cobra.Command, args []string) { + inputFile, _ := cmd.Flags().GetString("input") + outputFile, _ := cmd.Flags().GetString("output") + publicKeyPath, _ := cmd.Flags().GetString("publicKey") + + // Generate RSA keys if no public key is provided + var publicKey *rsa.PublicKey + var err error + rsa := &cryptography.RSAImpl{} + if publicKeyPath == "" { + // Generate RSA keys + + privateKey, pubKey, genErr := rsa.GenerateKeys(2048) + if genErr != nil { + log.Fatalf("Error generating RSA keys: %v\n", genErr) + } + publicKey = pubKey + + // Optionally save the private and public keys + err = rsa.SavePrivateKeyToFile(privateKey, "data/private_key.pem") + if err != nil { + log.Fatalf("Error saving private key: %v\n", err) + } + err = rsa.SavePublicKeyToFile(publicKey, "data/public_key.pem") + if err != nil { + log.Fatalf("Error saving public key: %v\n", err) + } + fmt.Println("Generated and saved RSA keys.") + } else { + // Read the provided public key + publicKey, err = rsa.ReadPublicKey(publicKeyPath) + if err != nil { + log.Fatalf("Error reading public key: %v\n", err) + } + } + + // Encrypt the file + plainText, err := utils.ReadFile(inputFile) + if err != nil { + log.Fatalf("Error reading input file: %v\n", err) + } + + encryptedData, err := rsa.Encrypt(plainText, publicKey) + if err != nil { + log.Fatalf("Error encrypting data: %v\n", err) + } + + // Save encrypted file + err = utils.WriteFile(outputFile, encryptedData) + if err != nil { + log.Fatalf("Error writing encrypted file: %v\n", err) + } + fmt.Printf("Encrypted data saved to %s\n", outputFile) +} + +func DecryptRSACmd(cmd *cobra.Command, args []string) { + inputFile, _ := cmd.Flags().GetString("input") + outputFile, _ := cmd.Flags().GetString("output") + privateKeyPath, _ := cmd.Flags().GetString("privateKey") + + // Generate RSA keys if no private key is provided + var privateKey *rsa.PrivateKey + var err error + rsa := &cryptography.RSAImpl{} + if privateKeyPath == "" { + // Generate RSA keys + privKey, _, genErr := rsa.GenerateKeys(2048) + if genErr != nil { + log.Fatalf("Error generating RSA keys: %v\n", genErr) + } + privateKey = privKey + + // Optionally save the private and public keys + err = rsa.SavePrivateKeyToFile(privateKey, "private_key.pem") + if err != nil { + log.Fatalf("Error saving private key: %v\n", err) + } + fmt.Println("Generated and saved private key.") + } else { + // Read the provided private key + privateKey, err = rsa.ReadPrivateKey(privateKeyPath) + if err != nil { + log.Fatalf("Error reading private key: %v\n", err) + } + } + + // Decrypt the file + encryptedData, err := utils.ReadFile(inputFile) + if err != nil { + log.Fatalf("Error reading encrypted file: %v\n", err) + } + + decryptedData, err := rsa.Decrypt(encryptedData, privateKey) + if err != nil { + log.Fatalf("Error decrypting data: %v\n", err) + } + + // Save decrypted file + err = utils.WriteFile(outputFile, decryptedData) + if err != nil { + log.Fatalf("Error writing decrypted file: %v\n", err) + } + fmt.Printf("Decrypted data saved to %s\n", outputFile) +} From 8c109de1fc19c79ff84c91788e62ba25e552bba8 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 15 Nov 2024 08:00:49 +0000 Subject: [PATCH 2/6] install necessary dependencies for pkcs#11 integration --- .devcontainer/devcontainer.json | 1 + README.md | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 6d284a8..be4a9c2 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -5,5 +5,6 @@ "image": "mcr.microsoft.com/vscode/devcontainers/go:1.21", // Features to add to the dev container. More info: https://containers.dev/features "features": {}, + "postCreateCommand": "apt-get update && apt-get install -y opensc softhsm", "remoteUser": "root" } \ No newline at end of file diff --git a/README.md b/README.md index 169ce93..5858988 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,16 @@ TBD ## Getting Started +### Preconditions + +- Install Go from the official Go website, or use this [devcontainer.json](../../.devcontainer/devcontainer.json) with the [DevContainer extensions in VS Code or other IDE supporting DevContainers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) +- If the `devcontainer.json` is not used, install the necessary dependencies for PKCS#11 integration on a later Linux distribution such as `Debian 12` or `Ubuntu 22.04`: + +```sh +apt-get update +apt-get install -y opensc softhsm +``` + ### Formatting and linting For formatting and linting run either on Unix systems From b0205b9a57202278799975753aa19fdc9ac2476d Mon Sep 17 00:00:00 2001 From: root Date: Fri, 15 Nov 2024 08:03:02 +0000 Subject: [PATCH 3/6] remove obsolete section --- cmd/crypto-vault-cli/README.md | 5 ----- cmd/crypto-vault-service/README.md | 5 ----- 2 files changed, 10 deletions(-) diff --git a/cmd/crypto-vault-cli/README.md b/cmd/crypto-vault-cli/README.md index 455c368..3797f70 100644 --- a/cmd/crypto-vault-cli/README.md +++ b/cmd/crypto-vault-cli/README.md @@ -3,17 +3,12 @@ ## Table of Contents + [Summary](#summary) -+ [Prerequisites](#prerequisites) + [Getting started](#getting-started) ## Summary `crypto-vault-cli` is a command-line tool for file encryption and decryption using AES, RSA and EC algorithms. It provides an easy interface to securely encrypt and decrypt files using symmetric (AES) and asymmetric (RSA, EC) cryptography. -## Prerequisites - -- Install Go from the official Go website, or use this [devcontainer.json](../../.devcontainer/devcontainer.json) with the [DevContainer extensions in VS Code or other IDE supporting DevContainers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) - ## Getting Started ### Encryption/Decryption diff --git a/cmd/crypto-vault-service/README.md b/cmd/crypto-vault-service/README.md index 90b353d..129ecbd 100644 --- a/cmd/crypto-vault-service/README.md +++ b/cmd/crypto-vault-service/README.md @@ -3,17 +3,12 @@ ## Table of Contents + [Summary](#summary) -+ [Prerequisites](#prerequisites) + [Getting started](#getting-started) ## Summary TBD -## Prerequisites - -TBD - ## Getting Started TBD \ No newline at end of file From 907d9a625d7915a87a589307dbc1943c032125bc Mon Sep 17 00:00:00 2001 From: root Date: Fri, 15 Nov 2024 08:52:20 +0000 Subject: [PATCH 4/6] add uuid package --- go.mod | 1 + go.sum | 2 ++ 2 files changed, 3 insertions(+) diff --git a/go.mod b/go.mod index 0906c4a..be43361 100644 --- a/go.mod +++ b/go.mod @@ -16,6 +16,7 @@ require ( github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.22.1 // indirect github.com/goccy/go-json v0.10.3 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/json-iterator/go v1.1.12 // indirect diff --git a/go.sum b/go.sum index 9cc2a1d..43390cf 100644 --- a/go.sum +++ b/go.sum @@ -29,6 +29,8 @@ github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaC github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= From b81e16029a4b3e52456a7c2008da8fc71e3efb7f Mon Sep 17 00:00:00 2001 From: root Date: Fri, 15 Nov 2024 08:52:59 +0000 Subject: [PATCH 5/6] modify commands and consider uuid as file name prefix --- cmd/crypto-vault-cli/crypto-vault-cli.go | 5 +- .../internal/commands/aes-commands.go | 24 +++++---- .../internal/commands/ecdsa-commands.go | 14 +++-- .../internal/commands/rsa-commands.go | 52 ++++++++++--------- 4 files changed, 56 insertions(+), 39 deletions(-) diff --git a/cmd/crypto-vault-cli/crypto-vault-cli.go b/cmd/crypto-vault-cli/crypto-vault-cli.go index e346443..2b2374a 100644 --- a/cmd/crypto-vault-cli/crypto-vault-cli.go +++ b/cmd/crypto-vault-cli/crypto-vault-cli.go @@ -32,7 +32,7 @@ func main() { } decryptAESFileCmd.Flags().StringP("input", "i", "", "Input encrypted file path") decryptAESFileCmd.Flags().StringP("output", "o", "", "Output decrypted file path") - decryptAESFileCmd.Flags().StringP("keyDir", "d", "", "Directory to read the encryption key from") + decryptAESFileCmd.Flags().StringP("symmetricKey", "k", "", "Path to the symmetric key") rootCmd.AddCommand(decryptAESFileCmd) // RSA Commands @@ -43,7 +43,8 @@ func main() { } encryptRSAFileCmd.Flags().StringP("input", "i", "", "Input file path") encryptRSAFileCmd.Flags().StringP("output", "o", "", "Output encrypted file path") - encryptRSAFileCmd.Flags().StringP("publicKey", "p", "", "Path to RSA public key") + encryptRSAFileCmd.Flags().StringP("keyDir", "d", "", "Directory to store the encryption key") + rootCmd.AddCommand(encryptRSAFileCmd) var decryptRSAFileCmd = &cobra.Command{ diff --git a/cmd/crypto-vault-cli/internal/commands/aes-commands.go b/cmd/crypto-vault-cli/internal/commands/aes-commands.go index b4dc16e..32ed547 100644 --- a/cmd/crypto-vault-cli/internal/commands/aes-commands.go +++ b/cmd/crypto-vault-cli/internal/commands/aes-commands.go @@ -8,10 +8,11 @@ import ( "os" "path/filepath" + "github.com/google/uuid" // Import UUID package "github.com/spf13/cobra" ) -// Encrypts a file using AES and saves the encryption key +// Encrypts a file using AES and saves the symmetric key with a UUID prefix func EncryptAESCmd(cmd *cobra.Command, args []string) { inputFile, _ := cmd.Flags().GetString("input") outputFile, _ := cmd.Flags().GetString("output") @@ -49,8 +50,11 @@ func EncryptAESCmd(cmd *cobra.Command, args []string) { } fmt.Printf("Encrypted data saved to %s\n", outputFile) - // Save the AES key to the specified key directory - keyFilePath := filepath.Join(keyDir, "encryption_key.bin") + // Generate a UUID for the key filename + uniqueID := uuid.New().String() // Generate a unique UUID + + // Save the AES key with the UUID prefix in the specified key directory + keyFilePath := filepath.Join(keyDir, fmt.Sprintf("%s-symmetric_key.bin", uniqueID)) err = utils.WriteFile(keyFilePath, key) if err != nil { log.Fatalf("Error writing AES key to file: %v\n", err) @@ -58,21 +62,21 @@ func EncryptAESCmd(cmd *cobra.Command, args []string) { fmt.Printf("AES key saved to %s\n", keyFilePath) } +// Decrypts a file using AES and reads the corresponding symmetric key with a UUID prefix func DecryptAESCmd(cmd *cobra.Command, args []string) { inputFile, _ := cmd.Flags().GetString("input") outputFile, _ := cmd.Flags().GetString("output") - keyDir, _ := cmd.Flags().GetString("keyDir") + symmetricKey, _ := cmd.Flags().GetString("symmetricKey") // Validate input arguments - if inputFile == "" || outputFile == "" || keyDir == "" { - log.Fatalf("Error: input, output, and keyDir flags are required\n") + if inputFile == "" || outputFile == "" || symmetricKey == "" { + log.Fatalf("Error: input, output and symmetricKey flags are required\n") } - // Read the encryption key from the specified directory - keyFilePath := filepath.Join(keyDir, "encryption_key.bin") - key, err := os.ReadFile(keyFilePath) + // Read the symmetric key from the file + key, err := os.ReadFile(symmetricKey) if err != nil { - log.Fatalf("Error reading encryption key from file: %v\n", err) + log.Fatalf("Error reading symmetric key from file: %v\n", err) } // Decrypt the file diff --git a/cmd/crypto-vault-cli/internal/commands/ecdsa-commands.go b/cmd/crypto-vault-cli/internal/commands/ecdsa-commands.go index 5257d92..c06a68c 100644 --- a/cmd/crypto-vault-cli/internal/commands/ecdsa-commands.go +++ b/cmd/crypto-vault-cli/internal/commands/ecdsa-commands.go @@ -10,6 +10,7 @@ import ( "log" "os" + "github.com/google/uuid" "github.com/spf13/cobra" ) @@ -19,6 +20,11 @@ func SignECCCmd(cmd *cobra.Command, args []string) { inputFile, _ := cmd.Flags().GetString("input") // File to sign keyDir, _ := cmd.Flags().GetString("keyDir") // Directory to save keys + // Validate input arguments + if inputFile == "" || keyDir == "" { + log.Fatalf("Error: input and keyDir flags are required\n") + } + // ECC implementation ecdsaImpl := &cryptography.ECDSAImpl{} var privateKey *ecdsa.PrivateKey @@ -46,9 +52,11 @@ func SignECCCmd(cmd *cobra.Command, args []string) { // Output the signature fmt.Printf("Signature: %x\n", signature) + uniqueID := uuid.New() // Save the private and public keys to files (if they were generated) if privateKey != nil && keyDir != "" { - privateKeyFilePath := fmt.Sprintf("%s/private_key.pem", keyDir) + privateKeyFilePath := fmt.Sprintf("%s/%s-private_key.pem", keyDir, uniqueID.String()) + err = ecdsaImpl.SavePrivateKeyToFile(privateKey, privateKeyFilePath) if err != nil { log.Fatalf("Error saving private key: %v\n", err) @@ -57,7 +65,7 @@ func SignECCCmd(cmd *cobra.Command, args []string) { } if publicKey != nil && keyDir != "" { - publicKeyFilePath := fmt.Sprintf("%s/public_key.pem", keyDir) + publicKeyFilePath := fmt.Sprintf("%s/%s-public_key.pem", keyDir, uniqueID.String()) err = ecdsaImpl.SavePublicKeyToFile(publicKey, publicKeyFilePath) if err != nil { log.Fatalf("Error saving public key: %v\n", err) @@ -67,7 +75,7 @@ func SignECCCmd(cmd *cobra.Command, args []string) { // Save the signature to a file in the data folder (optional, based on the input file) if keyDir != "" { - signatureFilePath := fmt.Sprintf("%s/signature.sig", keyDir) + signatureFilePath := fmt.Sprintf("%s/%s-signature.sig", keyDir, uniqueID.String()) err = ecdsaImpl.SaveSignatureToFile(signatureFilePath, signature) if err != nil { log.Fatalf("Error saving signature: %v\n", err) diff --git a/cmd/crypto-vault-cli/internal/commands/rsa-commands.go b/cmd/crypto-vault-cli/internal/commands/rsa-commands.go index 2093969..0cc8f43 100644 --- a/cmd/crypto-vault-cli/internal/commands/rsa-commands.go +++ b/cmd/crypto-vault-cli/internal/commands/rsa-commands.go @@ -7,6 +7,7 @@ import ( "fmt" "log" + "github.com/google/uuid" "github.com/spf13/cobra" ) @@ -14,38 +15,41 @@ import ( func EncryptRSACmd(cmd *cobra.Command, args []string) { inputFile, _ := cmd.Flags().GetString("input") outputFile, _ := cmd.Flags().GetString("output") - publicKeyPath, _ := cmd.Flags().GetString("publicKey") + keyDir, _ := cmd.Flags().GetString("keyDir") // Directory to save keys + + // Validate input arguments + if inputFile == "" || outputFile == "" || keyDir == "" { + log.Fatalf("Error: input, output and keyDir flags are required\n") + } // Generate RSA keys if no public key is provided var publicKey *rsa.PublicKey var err error rsa := &cryptography.RSAImpl{} - if publicKeyPath == "" { - // Generate RSA keys - privateKey, pubKey, genErr := rsa.GenerateKeys(2048) - if genErr != nil { - log.Fatalf("Error generating RSA keys: %v\n", genErr) - } - publicKey = pubKey + uniqueID := uuid.New() + // Generate RSA keys - // Optionally save the private and public keys - err = rsa.SavePrivateKeyToFile(privateKey, "data/private_key.pem") - if err != nil { - log.Fatalf("Error saving private key: %v\n", err) - } - err = rsa.SavePublicKeyToFile(publicKey, "data/public_key.pem") - if err != nil { - log.Fatalf("Error saving public key: %v\n", err) - } - fmt.Println("Generated and saved RSA keys.") - } else { - // Read the provided public key - publicKey, err = rsa.ReadPublicKey(publicKeyPath) - if err != nil { - log.Fatalf("Error reading public key: %v\n", err) - } + privateKey, publicKey, genErr := rsa.GenerateKeys(2048) + if genErr != nil { + log.Fatalf("Error generating RSA keys: %v\n", genErr) + } + + privateKeyFilePath := fmt.Sprintf("%s/%s-private_key.pem", keyDir, uniqueID.String()) + // Optionally save the private and public keys + err = rsa.SavePrivateKeyToFile(privateKey, privateKeyFilePath) + if err != nil { + log.Fatalf("Error saving private key: %v\n", err) + } + + publicKeyFilePath := fmt.Sprintf("%s/%s-public_key.pem", keyDir, uniqueID.String()) + err = rsa.SavePublicKeyToFile(publicKey, publicKeyFilePath) + if err != nil { + log.Fatalf("Error saving public key: %v\n", err) } + fmt.Println("Generated and saved RSA keys.") + fmt.Println("Private key path:", privateKeyFilePath) + fmt.Println("Public key path:", publicKeyFilePath) // Encrypt the file plainText, err := utils.ReadFile(inputFile) From 637d20527d52d9c42576ed4df559c48861e98877 Mon Sep 17 00:00:00 2001 From: Marvin Gajek Date: Fri, 15 Nov 2024 09:55:07 +0100 Subject: [PATCH 6/6] update README of crypto-vault-cli app --- cmd/crypto-vault-cli/README.md | 40 ++++++++++------------------------ 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/cmd/crypto-vault-cli/README.md b/cmd/crypto-vault-cli/README.md index 3797f70..da5a96d 100644 --- a/cmd/crypto-vault-cli/README.md +++ b/cmd/crypto-vault-cli/README.md @@ -11,49 +11,33 @@ ## Getting Started +**NOTE**: Keys will be generated internally during the encryption or signature generation operations. + ### Encryption/Decryption **AES example** ```sh +uuid=$(cat /proc/sys/kernel/random/uuid) # Encryption -go run crypto-vault-cli.go encrypt-aes --input data/input.txt --output data/output.enc --keySize 16 --keyDir data/ +go run crypto-vault-cli.go encrypt-aes --input data/input.txt --output data/${uuid}-output.enc --keySize 16 --keyDir data/ # Decryption -go run crypto-vault-cli.go decrypt-aes --input data/output.enc --output data/decrypted.txt --keyDir data/ +go run crypto-vault-cli.go decrypt-aes --input data/${uuid}-output.enc --output data/${uuid}-decrypted.txt --symmetricKey ``` -**RSA Example considering external key generation** +**RSA Example** ```sh -cd data -openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048 -openssl rsa -pubout -in private_key.pem -out public_key.pem -cd - +uuid=$(cat /proc/sys/kernel/random/uuid) # Encryption -go run crypto-vault-cli.go encrypt-rsa --input data/input.txt --output data/encryptedII.txt --publicKey data/public_key.pem +go run crypto-vault-cli.go encrypt-rsa --input data/input.txt --output data/${uuid}-encrypted.txt --keyDir data/ # Decryption -go run crypto-vault-cli.go decrypt-rsa --input data/encryptedII.txt --output data/decryptedII.txt --privateKey data/private_key.pem -``` - -**RSA Example considering internal key generation** - -```sh -# Encryption -go run crypto-vault-cli.go encrypt-rsa --input data/input.txt --output data/encryptedII.txt - -# Decryption -go run crypto-vault-cli.go decrypt-rsa --input data/encryptedII.txt --output data/decryptedII.txt --privateKey data/private_key.pem -``` - -**RSA with PKCS#11 Example considering external key generation** - -```sh -TBD +go run crypto-vault-cli.go decrypt-rsa --input data/${uuid}-encrypted.txt --output data/${uuid}-decrypted.txt --privateKey ``` -**RSA with PKCS#11 Example considering internal key generation** +**RSA with PKCS#11 Example** ```sh TBD @@ -61,12 +45,12 @@ TBD ### Hashing / Verifying signatures -**ECDSA Example considering internal key generation** +**ECDSA Example** ```sh # Sign a file with a newly generated ECC key pair (internally generated) go run crypto-vault-cli.go sign-ecc --input data/input.txt --keyDir data # Verify the signature using the generated public key -go run crypto-vault-cli.go verify-ecc --input data/input.txt --publicKey data/public_key.pem --signature data/signature.sig +go run crypto-vault-cli.go verify-ecc --input data/input.txt --publicKey --signature ``` \ No newline at end of file