Created
February 18, 2022 16:37
-
-
Save alex-bezverkhniy/d7e2b96cbb696490f9b2568e90e3bc6d to your computer and use it in GitHub Desktop.
Simple tool to encrypt/decrypt (+ encode/decode base64)
This file contains hidden or 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
| package main | |
| import ( | |
| "crypto/aes" | |
| "crypto/cipher" | |
| "crypto/rand" | |
| b64 "encoding/base64" | |
| "errors" | |
| "fmt" | |
| "os" | |
| ) | |
| const EncryptCmd = "encrypt" | |
| const DecryptCmd = "decrypt" | |
| const EncodeCmd = "encode" | |
| const DecodeCmd = "decode" | |
| const PackCmd = "pack" | |
| const UnpackCmd = "unpack" | |
| const KeyCmd = "key" | |
| func main() { | |
| if len(os.Args) >= 2 { | |
| cmd := os.Args[1] | |
| switch cmd { | |
| case EncryptCmd: | |
| { | |
| key, destPath, data, err := parseArgs(os.Args) | |
| if err != nil { | |
| fmt.Println(err.Error()) | |
| PrintUsage() | |
| os.Exit(-1) | |
| } | |
| encData, err := Encrypt([]byte(key), data) | |
| check(err) | |
| os.WriteFile(destPath, encData, 0644) | |
| } | |
| case DecryptCmd: | |
| { | |
| key, destPath, data, err := parseArgs(os.Args) | |
| if err != nil { | |
| fmt.Println(err.Error()) | |
| PrintUsage() | |
| os.Exit(-1) | |
| } | |
| encData, err := Decrypt([]byte(key), data) | |
| check(err) | |
| os.WriteFile(destPath, encData, 0644) | |
| } | |
| case EncodeCmd: | |
| { | |
| if len(os.Args) < 2 { | |
| PrintUsage() | |
| os.Exit(-1) | |
| } | |
| srcFile := os.Args[2] | |
| data, err := os.ReadFile(srcFile) | |
| if err != nil { | |
| fmt.Println(err.Error()) | |
| PrintUsage() | |
| os.Exit(-1) | |
| } | |
| fmt.Println(Encode(data)) | |
| } | |
| case DecodeCmd: | |
| { | |
| destPath, data, err := parseArgsDecode(os.Args) | |
| if err != nil { | |
| fmt.Println(err.Error()) | |
| PrintUsage() | |
| os.Exit(-1) | |
| } | |
| encData, err := Decode(string(data)) | |
| check(err) | |
| err = os.WriteFile(destPath, encData, 0644) | |
| if err != nil { | |
| fmt.Println(err.Error()) | |
| PrintUsage() | |
| os.Exit(-1) | |
| } | |
| } | |
| case PackCmd: | |
| { | |
| key, destPath, data, err := parseArgs(os.Args) | |
| d, err := Pack([]byte(key), data) | |
| if err != nil { | |
| fmt.Println(err.Error()) | |
| PrintUsage() | |
| os.Exit(-1) | |
| } | |
| os.WriteFile(destPath, d, 0644) | |
| if err != nil { | |
| fmt.Println(err.Error()) | |
| PrintUsage() | |
| os.Exit(-1) | |
| } | |
| } | |
| case UnpackCmd: | |
| { | |
| key, destPath, data, err := parseArgs(os.Args) | |
| d, err := Unpack([]byte(key), data) | |
| if err != nil { | |
| fmt.Println(err.Error()) | |
| PrintUsage() | |
| os.Exit(-1) | |
| } | |
| os.WriteFile(destPath, d, 0644) | |
| if err != nil { | |
| fmt.Println(err.Error()) | |
| PrintUsage() | |
| os.Exit(-1) | |
| } | |
| } | |
| case KeyCmd: | |
| { | |
| key, err := GenerateKey() | |
| check(err) | |
| fmt.Println(len(key)) | |
| } | |
| default: | |
| PrintUsage() | |
| } | |
| } else { | |
| PrintUsage() | |
| } | |
| } | |
| func Encrypt(key, data []byte) ([]byte, error) { | |
| blockCipher, err := aes.NewCipher(key) | |
| if err != nil { | |
| return nil, err | |
| } | |
| gcm, err := cipher.NewGCM(blockCipher) | |
| if err != nil { | |
| return nil, err | |
| } | |
| nonce := make([]byte, gcm.NonceSize()) | |
| if _, err = rand.Read(nonce); err != nil { | |
| return nil, err | |
| } | |
| ciphertext := gcm.Seal(nonce, nonce, data, nil) | |
| return ciphertext, nil | |
| } | |
| func Decrypt(key, data []byte) ([]byte, error) { | |
| blockCipher, err := aes.NewCipher(key) | |
| if err != nil { | |
| fmt.Println("key error") | |
| return nil, err | |
| } | |
| gcm, err := cipher.NewGCM(blockCipher) | |
| if err != nil { | |
| fmt.Println("gcm error") | |
| return nil, err | |
| } | |
| nonce, ciphertext := data[:gcm.NonceSize()], data[gcm.NonceSize():] | |
| plaintext, err := gcm.Open(nil, nonce, ciphertext, nil) | |
| if err != nil { | |
| fmt.Println("open error") | |
| return nil, err | |
| } | |
| return plaintext, nil | |
| } | |
| func Encode(data []byte) string { | |
| return b64.StdEncoding.EncodeToString(data) | |
| } | |
| func Decode(data string) ([]byte, error) { | |
| return b64.StdEncoding.DecodeString(data) | |
| } | |
| func GenerateKey() ([]byte, error) { | |
| key := make([]byte, 32) | |
| _, err := rand.Read(key) | |
| if err != nil { | |
| return nil, err | |
| } | |
| return key, nil | |
| } | |
| func Pack(key, data []byte) ([]byte, error) { | |
| d, err := Encrypt(key, data) | |
| if err != nil { | |
| return nil, err | |
| } | |
| b64Str := Encode(d) | |
| return []byte(b64Str), nil | |
| } | |
| func Unpack(key, data []byte) ([]byte, error) { | |
| d, err := Decode(string(data)) | |
| if err != nil { | |
| return nil, err | |
| } | |
| return Decrypt(key, d) | |
| } | |
| func PrintUsage() { | |
| fmt.Printf(`usage: | |
| Encrypting/Decrypting: | |
| ende-docs <command> <key> <sourcePath> <destPath> | |
| where: | |
| <command> - encrypt or decrypt | |
| Base64 Encoding/Decoding: | |
| ende-docs <command> <sourcePath> (<destPath> for decoding) | |
| where: | |
| <command> - encode or decode | |
| Encryption+Base64 Pack/Upnack: | |
| ende-docs <command> <key> <sourcePath> <destPath> | |
| where: | |
| <command> - pack or unpack | |
| `) | |
| } | |
| func check(e error) { | |
| if e != nil { | |
| fmt.Printf("%s\n", e.Error()) | |
| os.Exit(-1) | |
| } | |
| } | |
| func parseArgs(args []string) (string, string, []byte, error) { | |
| key := os.Args[2] | |
| if len(os.Args) < 5 { | |
| return "", "", nil, errors.New("Not enough arguments") | |
| } | |
| srcPath := os.Args[3] | |
| destPath := os.Args[4] | |
| data, err := os.ReadFile(srcPath) | |
| if err != nil { | |
| return "", "", nil, err | |
| } | |
| return key, destPath, data, nil | |
| } | |
| func parseArgsDecode(args []string) (string, []byte, error) { | |
| if len(os.Args) < 4 { | |
| return "", nil, errors.New("Not enough arguments") | |
| } | |
| srcPath := os.Args[2] | |
| destPath := os.Args[3] | |
| data, err := os.ReadFile(srcPath) | |
| if err != nil { | |
| return "", nil, err | |
| } | |
| return destPath, data, nil | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment