/* Copyright © 2024 Brian Buller */ package util import ( "crypto/aes" "crypto/cipher" "crypto/rand" "encoding/base64" "encoding/hex" "errors" "fmt" "io" "time" ) func GenTodayKey() string { key := []byte(time.Now().Format(fmt.Sprintf("%s%s%s ", time.DateOnly, time.DateOnly, time.DateOnly))) return hex.EncodeToString(key) //convert to string for saving } func Encrypt(key, input string) (string, error) { btKey, _ := hex.DecodeString(key) plaintext := []byte(input) // Create a new Cipher Block from the key block, err := aes.NewCipher(btKey) if err != nil { return "", err } ciphertext := make([]byte, aes.BlockSize+len(plaintext)) iv := ciphertext[:aes.BlockSize] if _, err := io.ReadFull(rand.Reader, iv); err != nil { return "", err } stream := cipher.NewCFBEncrypter(block, iv) stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext) // Convert to base64 return base64.URLEncoding.EncodeToString(ciphertext), nil } func Decrypt(key, input string) (string, error) { btKey, _ := hex.DecodeString(key) ciphertext, _ := base64.URLEncoding.DecodeString(input) block, err := aes.NewCipher(btKey) if err != nil { return "", err } if len(ciphertext) < aes.BlockSize { return "", errors.New("ciphertext is too short") } iv := ciphertext[:aes.BlockSize] ciphertext = ciphertext[aes.BlockSize:] stream := cipher.NewCFBDecrypter(block, iv) // XORKeyStream can work in-place if the two arguments are the same. stream.XORKeyStream(ciphertext, ciphertext) return fmt.Sprintf("%s", ciphertext), nil }