From 978021293f92735c9222a9f7efb98eaa11f45e15 Mon Sep 17 00:00:00 2001 From: shazbert Date: Fri, 3 Mar 2017 09:16:20 +1100 Subject: [PATCH] Added basic encryption service for JSON file --- encryption.go | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 encryption.go diff --git a/encryption.go b/encryption.go new file mode 100644 index 00000000..098756db --- /dev/null +++ b/encryption.go @@ -0,0 +1,142 @@ +package main + +import ( + "bytes" + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "log" + "os" +) + +const ( + ENCRYPTION_CONFIRMATION_STRING = "THORS-HAMMER" +) + +type Encryption struct { + CryptoKey []byte + EncryptedFile []byte + Nonce []byte + encrypPerm bool + decryptPerm bool +} + +func (e *Encryption) SetUp() { + for len(e.CryptoKey) != 32 { + fmt.Println("Please enter a unique 32Char key to set up encryption: \n") + + _, err := fmt.Scanln(&e.CryptoKey) + if err != nil { + panic(err) + } + + if len(e.CryptoKey) > 32 || len(e.CryptoKey) < 32 { + fmt.Println("Please Re-enter a 32char key..\n") + } + } + + e.Nonce = make([]byte, 12) + if _, err := io.ReadFull(rand.Reader, e.Nonce); err != nil { + panic(err) + } + + e.encrypPerm = false + e.decryptPerm = false +} + +func (e *Encryption) Encrypt() []byte { + block, err := aes.NewCipher(e.CryptoKey) + if err != nil { + panic(err) + } + + aesgcm, err := cipher.NewGCM(block) + if err != nil { + panic(err) + } + + configfile := e.ReadFile(CONFIG_FILE) + + if e.ConfirmJSON(configfile) != true { + log.Println("File cannot be encrypted.\n") + if e.ConfirmECS(configfile) != true { + log.Println("File Corrupted.") + panic(err) + } + log.Println("File already encrypted.") + return configfile + } + e.EncryptedFile = aesgcm.Seal(nil, e.Nonce, configfile, nil) + + appendedFile := []byte(ENCRYPTION_CONFIRMATION_STRING) + appendedFile = append(appendedFile, e.EncryptedFile...) + return appendedFile +} + +func (e *Encryption) Decrypt() []byte { + blockDecrypt, err := aes.NewCipher(e.CryptoKey) + if err != nil { + panic(err) + } + + aesgcmDecrypt, err := cipher.NewGCM(blockDecrypt) + if err != nil { + panic(err) + } + + configfile := e.ReadFile(CONFIG_FILE) + if e.ConfirmECS(configfile) != true { + log.Println("File cannot be decrypted..\n") + if e.ConfirmJSON(configfile) != true { + log.Println("File corrupted.") + panic(err) + } + log.Println("File already decrypted.") + return configfile + } + + unencryptedFile, err := aesgcmDecrypt.Open(nil, e.Nonce, e.RemoveECS(configfile), nil) + if err != nil { + log.Println("File Corrupted") + panic(err) + } + return unencryptedFile +} + +func (e *Encryption) ReadFile(filename string) []byte { + file, err := ioutil.ReadFile(filename) + if err != nil { + panic(err) + } + return file +} + +func (e *Encryption) SaveFile(file []byte) { + mode := int(0777) + perm := os.FileMode(mode) + err := ioutil.WriteFile(CONFIG_FILE, file, perm) + if err != nil { + panic(err) + } +} + +func (e *Encryption) ConfirmJSON(file []byte) bool { + err := json.Unmarshal(file, nil) //Needs Revision + if err != nil { + return true //Fix after revision + } + return true +} + +func (e *Encryption) ConfirmECS(file []byte) bool { + subslice := []byte(ENCRYPTION_CONFIRMATION_STRING) + return bytes.Contains(file, subslice) +} + +func (e *Encryption) RemoveECS(file []byte) []byte { + return bytes.Trim(file, ENCRYPTION_CONFIRMATION_STRING) +}