Spaces:
Running
Running
| // internal/shared/crypto/encryption.go | |
| package crypto | |
| import ( | |
| "crypto/aes" | |
| "crypto/cipher" | |
| "crypto/rand" | |
| "encoding/base64" | |
| "errors" | |
| "io" | |
| "os" | |
| "crypto/sha256" | |
| ) | |
| func Encrypt(plain string) (string, error) { | |
| key := []byte(os.Getenv("SESSION_SECRET")) | |
| if len(key) != 32 { | |
| return "", errors.New("SESSION_SECRET must be 32 bytes") | |
| } | |
| block, err := aes.NewCipher(key) | |
| if err != nil { | |
| return "", err | |
| } | |
| gcm, err := cipher.NewGCM(block) | |
| if err != nil { | |
| return "", err | |
| } | |
| nonce := make([]byte, gcm.NonceSize()) | |
| if _, err := io.ReadFull(rand.Reader, nonce); err != nil { | |
| return "", err | |
| } | |
| ciphertext := gcm.Seal(nonce, nonce, []byte(plain), nil) | |
| return base64.StdEncoding.EncodeToString(ciphertext), nil | |
| } | |
| func Decrypt(enc string) (string, error) { | |
| key := []byte(os.Getenv("SESSION_SECRET")) | |
| data, err := base64.StdEncoding.DecodeString(enc) | |
| if err != nil { | |
| return "", err | |
| } | |
| block, err := aes.NewCipher(key) | |
| if err != nil { | |
| return "", err | |
| } | |
| gcm, err := cipher.NewGCM(block) | |
| if err != nil { | |
| return "", err | |
| } | |
| nonceSize := gcm.NonceSize() | |
| if len(data) < nonceSize { | |
| return "", errors.New("invalid ciphertext") | |
| } | |
| nonce, ciphertext := data[:nonceSize], data[nonceSize:] | |
| plain, err := gcm.Open(nil, nonce, ciphertext, nil) | |
| if err != nil { | |
| return "", err | |
| } | |
| return string(plain), nil | |
| } | |
| func SHA256Base64URL(input string) string { | |
| hash := sha256.Sum256([]byte(input)) | |
| return base64.RawURLEncoding.EncodeToString(hash[:]) | |
| } | |