Decrypt decrypts a prefixed base64 string back to plaintext.
(encrypted string, key []byte)
| 146 | |
| 147 | // Decrypt decrypts a prefixed base64 string back to plaintext. |
| 148 | func Decrypt(encrypted string, key []byte) (string, error) { |
| 149 | if encrypted == "" { |
| 150 | return "", nil |
| 151 | } |
| 152 | if !IsEncrypted(encrypted) { |
| 153 | return encrypted, nil |
| 154 | } |
| 155 | |
| 156 | data, err := base64.StdEncoding.DecodeString(encrypted[len(encryptedPrefix):]) |
| 157 | if err != nil { |
| 158 | return "", fmt.Errorf("failed to decode encrypted value: %w", err) |
| 159 | } |
| 160 | |
| 161 | block, err := aes.NewCipher(key) |
| 162 | if err != nil { |
| 163 | return "", err |
| 164 | } |
| 165 | |
| 166 | aesGCM, err := cipher.NewGCM(block) |
| 167 | if err != nil { |
| 168 | return "", err |
| 169 | } |
| 170 | |
| 171 | nonceSize := aesGCM.NonceSize() |
| 172 | if len(data) < nonceSize { |
| 173 | return "", fmt.Errorf("ciphertext too short") |
| 174 | } |
| 175 | |
| 176 | nonce, ciphertext := data[:nonceSize], data[nonceSize:] |
| 177 | plaintext, err := aesGCM.Open(nil, nonce, ciphertext, nil) |
| 178 | if err != nil { |
| 179 | return "", fmt.Errorf("decryption failed: %w", err) |
| 180 | } |
| 181 | |
| 182 | return string(plaintext), nil |
| 183 | } |
| 184 | |
| 185 | // IsEncrypted checks if a value has the encrypted prefix. |
| 186 | func IsEncrypted(s string) bool { |