Last active
December 29, 2023 13:17
-
-
Save Myestery/8b16dece79b1066799a09b834a6e00ce to your computer and use it in GitHub Desktop.
Golang AES 2 way encryption
This file contains 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 ( | |
"bytes" | |
"crypto/aes" | |
"crypto/cipher" | |
"encoding/base64" | |
"encoding/json" | |
"flag" | |
"fmt" | |
"os" | |
) | |
// OperationResult represents the result of an encryption or decryption operation | |
type OperationResult struct { | |
Result string `json:"result"` | |
Status bool `json:"status"` | |
Error string `json:"error,omitempty"` | |
} | |
// GetAESDecrypted decrypts given text in AES 256 CBC | |
func GetAESDecrypted(encrypted string, key string, iv string) (*OperationResult, *OperationResult) { | |
ciphertext, err := base64.StdEncoding.DecodeString(encrypted) | |
if err != nil { | |
return nil, &OperationResult{Status: false, Error: err.Error()} | |
} | |
block, err := aes.NewCipher([]byte(key)) | |
if err != nil { | |
return nil, &OperationResult{Status: false, Error: err.Error()} | |
} | |
if len(ciphertext)%aes.BlockSize != 0 { | |
return nil, &OperationResult{Status: false, Error: "block size must be a multiple of 16"} | |
} | |
mode := cipher.NewCBCDecrypter(block, []byte(iv)) | |
mode.CryptBlocks(ciphertext, ciphertext) | |
ciphertext = PKCS5UnPadding(ciphertext) | |
return &OperationResult{Result: string(ciphertext), Status: true}, nil | |
} | |
// PKCS5UnPadding pads a certain blob of data with necessary data to be used in AES block cipher | |
func PKCS5UnPadding(src []byte) []byte { | |
length := len(src) | |
unpadding := int(src[length-1]) | |
return src[:(length - unpadding)] | |
} | |
// GetAESEncrypted encrypts given text in AES 256 CBC | |
func GetAESEncrypted(plaintext string, key string, iv string) (*OperationResult, *OperationResult) { | |
var plainTextBlock []byte | |
length := len(plaintext) | |
if length%16 != 0 { | |
extendBlock := 16 - (length % 16) | |
plainTextBlock = make([]byte, length+extendBlock) | |
copy(plainTextBlock[length:], bytes.Repeat([]byte{uint8(extendBlock)}, extendBlock)) | |
} else { | |
plainTextBlock = make([]byte, length) | |
} | |
copy(plainTextBlock, plaintext) | |
block, err := aes.NewCipher([]byte(key)) | |
if err != nil { | |
return nil, &OperationResult{Status: false, Error: err.Error()} | |
} | |
ciphertext := make([]byte, len(plainTextBlock)) | |
mode := cipher.NewCBCEncrypter(block, []byte(iv)) | |
mode.CryptBlocks(ciphertext, plainTextBlock) | |
result := base64.StdEncoding.EncodeToString(ciphertext) | |
return &OperationResult{Result: result, Status: true}, nil | |
} | |
func main() { | |
var ( | |
plainText string | |
key string | |
iv string | |
encrypt bool | |
decrypt bool | |
) | |
flag.StringVar(&plainText, "text", "", "Text to encrypt or decrypt") | |
flag.StringVar(&key, "key", "my32digitkey12345678901234567890", "Encryption key (32 characters)") | |
flag.StringVar(&iv, "iv", "my16digitIvKey12", "Initialization vector (16 characters)") | |
flag.BoolVar(&encrypt, "encrypt", false, "Encrypt mode") | |
flag.BoolVar(&decrypt, "decrypt", false, "Decrypt mode") | |
flag.Parse() | |
if plainText == "" { | |
fmt.Println("Error: Specify the text using the -text flag.") | |
os.Exit(1) | |
} | |
if encrypt && decrypt { | |
fmt.Println("Error: Choose either -encrypt or -decrypt, not both.") | |
os.Exit(1) | |
} | |
if encrypt { | |
result, err := GetAESEncrypted(plainText, key, iv) | |
if err != nil { | |
resultJSON, _ := json.Marshal(err) | |
fmt.Println(string(resultJSON)) | |
os.Exit(0) | |
} | |
resultJSON, _ := json.Marshal(result) | |
fmt.Println(string(resultJSON)) | |
} else if decrypt { | |
result, err := GetAESDecrypted(plainText, key, iv) | |
if err != nil { | |
resultJSON, _ := json.Marshal(err) | |
fmt.Println(string(resultJSON)) | |
os.Exit(0) | |
} | |
resultJSON, _ := json.Marshal(result) | |
fmt.Println(string(resultJSON)) | |
} else { | |
fmt.Println("Error: Choose either -encrypt or -decrypt.") | |
os.Exit(0) | |
} | |
} | |
// go run crypto.go -decrypt -text "7xIb/yiNp8JsPQlmNhIk9Q==" -key "my32digitkey12345678901234567890" -iv "my16digitIvKey12" | |
// go run crypto.go -encrypt "xxxx" -key "|<b631h<f8nH7nGy4<8dO0TW{\)LPWq3" -iv "*e6-pyQyT9X2%HsI" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment