Skip to content

Commit 4498a26

Browse files
authored
Improve decryption failure message (go-gitea#24573) (go-gitea#24575)
Backport go-gitea#24573 Help some users like go-gitea#16832 go-gitea#1851 There are many users reporting similar problem: if the SECRET_KEY mismatches, some operations (like 2FA login) only reports unclear 500 error and unclear "base64 decode error" log (some maintainers ever spent a lot of time on debugging such problem) The SECRET_KEY was not well-designed and it is also a kind of technical debt. Since it couldn't be fixed easily, it's good to add clearer error messages, then at least users could know what the real problem is.
1 parent 6f57be0 commit 4498a26

File tree

2 files changed

+26
-17
lines changed

2 files changed

+26
-17
lines changed

modules/secret/secret.go

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,21 @@ import (
1111
"encoding/base64"
1212
"encoding/hex"
1313
"errors"
14+
"fmt"
1415
"io"
1516
)
1617

1718
// AesEncrypt encrypts text and given key with AES.
1819
func AesEncrypt(key, text []byte) ([]byte, error) {
1920
block, err := aes.NewCipher(key)
2021
if err != nil {
21-
return nil, err
22+
return nil, fmt.Errorf("AesEncrypt invalid key: %v", err)
2223
}
2324
b := base64.StdEncoding.EncodeToString(text)
2425
ciphertext := make([]byte, aes.BlockSize+len(b))
2526
iv := ciphertext[:aes.BlockSize]
26-
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
27-
return nil, err
27+
if _, err = io.ReadFull(rand.Reader, iv); err != nil {
28+
return nil, fmt.Errorf("AesEncrypt unable to read IV: %w", err)
2829
}
2930
cfb := cipher.NewCFBEncrypter(block, iv)
3031
cfb.XORKeyStream(ciphertext[aes.BlockSize:], []byte(b))
@@ -38,15 +39,15 @@ func AesDecrypt(key, text []byte) ([]byte, error) {
3839
return nil, err
3940
}
4041
if len(text) < aes.BlockSize {
41-
return nil, errors.New("ciphertext too short")
42+
return nil, errors.New("AesDecrypt ciphertext too short")
4243
}
4344
iv := text[:aes.BlockSize]
4445
text = text[aes.BlockSize:]
4546
cfb := cipher.NewCFBDecrypter(block, iv)
4647
cfb.XORKeyStream(text, text)
4748
data, err := base64.StdEncoding.DecodeString(string(text))
4849
if err != nil {
49-
return nil, err
50+
return nil, fmt.Errorf("AesDecrypt invalid decrypted base64 string: %w", err)
5051
}
5152
return data, nil
5253
}
@@ -57,21 +58,21 @@ func EncryptSecret(key, str string) (string, error) {
5758
plaintext := []byte(str)
5859
ciphertext, err := AesEncrypt(keyHash[:], plaintext)
5960
if err != nil {
60-
return "", err
61+
return "", fmt.Errorf("failed to encrypt by secret: %w", err)
6162
}
6263
return hex.EncodeToString(ciphertext), nil
6364
}
6465

6566
// DecryptSecret decrypts a previously encrypted hex string
66-
func DecryptSecret(key, cipherhex string) (string, error) {
67+
func DecryptSecret(key, cipherHex string) (string, error) {
6768
keyHash := sha256.Sum256([]byte(key))
68-
ciphertext, err := hex.DecodeString(cipherhex)
69+
ciphertext, err := hex.DecodeString(cipherHex)
6970
if err != nil {
70-
return "", err
71+
return "", fmt.Errorf("failed to decrypt by secret, invalid hex string: %w", err)
7172
}
7273
plaintext, err := AesDecrypt(keyHash[:], ciphertext)
7374
if err != nil {
74-
return "", err
75+
return "", fmt.Errorf("failed to decrypt by secret, the key (maybe SECRET_KEY?) might be incorrect: %w", err)
7576
}
7677
return string(plaintext), nil
7778
}

modules/secret/secret_test.go

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,22 @@ import (
1010
)
1111

1212
func TestEncryptDecrypt(t *testing.T) {
13-
var hex string
14-
var str string
13+
hex, err := EncryptSecret("foo", "baz")
14+
assert.NoError(t, err)
15+
str, _ := DecryptSecret("foo", hex)
16+
assert.Equal(t, "baz", str)
1517

16-
hex, _ = EncryptSecret("foo", "baz")
18+
hex, err = EncryptSecret("bar", "baz")
19+
assert.NoError(t, err)
1720
str, _ = DecryptSecret("foo", hex)
18-
assert.Equal(t, str, "baz")
21+
assert.NotEqual(t, "baz", str)
1922

20-
hex, _ = EncryptSecret("bar", "baz")
21-
str, _ = DecryptSecret("foo", hex)
22-
assert.NotEqual(t, str, "baz")
23+
_, err = DecryptSecret("a", "b")
24+
assert.ErrorContains(t, err, "invalid hex string")
25+
26+
_, err = DecryptSecret("a", "bb")
27+
assert.ErrorContains(t, err, "the key (maybe SECRET_KEY?) might be incorrect: AesDecrypt ciphertext too short")
28+
29+
_, err = DecryptSecret("a", "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")
30+
assert.ErrorContains(t, err, "the key (maybe SECRET_KEY?) might be incorrect: AesDecrypt invalid decrypted base64 string")
2331
}

0 commit comments

Comments
 (0)