github.com/hungdoo/bot@v0.0.0-20240325145135-dd1f386f7b81/src/packages/command/tomb/secret.go (about) 1 package tomb 2 3 import ( 4 "crypto/aes" 5 "crypto/cipher" 6 "crypto/ecdsa" 7 "crypto/rand" 8 "encoding/base64" 9 "fmt" 10 "io" 11 "os" 12 "strings" 13 14 "github.com/ethereum/go-ethereum/crypto" 15 "github.com/hungdoo/bot/src/packages/dotenv" 16 ) 17 18 // Encrypt encrypts the plaintext using AES-GCM encryption. 19 func Encrypt(plaintext []byte, key []byte) (string, error) { 20 block, err := aes.NewCipher(key) 21 if err != nil { 22 return "", err 23 } 24 25 gcm, err := cipher.NewGCM(block) 26 if err != nil { 27 return "", err 28 } 29 30 nonce := make([]byte, gcm.NonceSize()) 31 if _, err := io.ReadFull(rand.Reader, nonce); err != nil { 32 return "", err 33 } 34 35 ciphertext := gcm.Seal(nonce, nonce, plaintext, nil) 36 return base64.StdEncoding.EncodeToString(ciphertext), nil 37 } 38 39 // Decrypt decrypts the ciphertext using AES-GCM decryption. 40 func Decrypt(ciphertext string, key []byte) ([]byte, error) { 41 block, err := aes.NewCipher(key) 42 if err != nil { 43 return nil, err 44 } 45 46 gcm, err := cipher.NewGCM(block) 47 if err != nil { 48 return nil, err 49 } 50 51 decodedCiphertext, err := base64.StdEncoding.DecodeString(ciphertext) 52 if err != nil { 53 return nil, err 54 } 55 56 nonceSize := gcm.NonceSize() 57 if len(decodedCiphertext) < nonceSize { 58 return nil, fmt.Errorf("ciphertext is too short") 59 } 60 61 nonce, cipher := decodedCiphertext[:nonceSize], decodedCiphertext[nonceSize:] 62 plaintext, err := gcm.Open(nil, nonce, cipher, nil) 63 if err != nil { 64 return nil, err 65 } 66 67 return plaintext, nil 68 } 69 70 func LoadSecrets(idx int, key string) (*ecdsa.PrivateKey, error) { 71 encryptedContent, err := os.ReadFile(dotenv.GetEnv("SECRET_FILE")) 72 if err != nil { 73 return nil, err 74 } 75 76 encryptedSecrets := strings.Split(string(encryptedContent), ",") 77 if len(encryptedSecrets) <= idx { 78 return nil, fmt.Errorf("encryptedSecrets out-of-bound: length[%v], idx[%v]", len(encryptedSecrets), idx) 79 } 80 81 // Convert the byte slice to a string (assuming the secret is text-based) 82 decrypted, err := Decrypt(string(encryptedSecrets[idx]), []byte(key)) 83 if err != nil { 84 return nil, err 85 } 86 87 pk, err := crypto.HexToECDSA(string(decrypted)) 88 if err != nil { 89 return nil, err 90 } 91 return pk, nil 92 }