forked from NYANDEV/forgejo
0d8478cff8
- In Go 1.21 the crypto/sha256 [got a massive
improvement](https://go.dev/doc/go1.21#crypto/sha256) by utilizing the
SHA instructions for AMD64 CPUs, which sha256-simd already was doing.
The performance is now on par and I think it's preferable to use the
standard library rather than a package when possible.
```
cpu: AMD Ryzen 5 3600X 6-Core Processor
│ simd.txt │ go.txt │
│ sec/op │ sec/op vs base │
Hash/8Bytes-12 63.25n ± 1% 73.38n ± 1% +16.02% (p=0.002 n=6)
Hash/64Bytes-12 98.73n ± 1% 105.30n ± 1% +6.65% (p=0.002 n=6)
Hash/1K-12 567.2n ± 1% 572.8n ± 1% +0.99% (p=0.002 n=6)
Hash/8K-12 4.062µ ± 1% 4.062µ ± 1% ~ (p=0.396 n=6)
Hash/1M-12 512.1µ ± 0% 510.6µ ± 1% ~ (p=0.485 n=6)
Hash/5M-12 2.556m ± 1% 2.564m ± 0% ~ (p=0.093 n=6)
Hash/10M-12 5.112m ± 0% 5.127m ± 0% ~ (p=0.093 n=6)
geomean 13.82µ 14.27µ +3.28%
│ simd.txt │ go.txt │
│ B/s │ B/s vs base │
Hash/8Bytes-12 120.6Mi ± 1% 104.0Mi ± 1% -13.81% (p=0.002 n=6)
Hash/64Bytes-12 618.2Mi ± 1% 579.8Mi ± 1% -6.22% (p=0.002 n=6)
Hash/1K-12 1.682Gi ± 1% 1.665Gi ± 1% -0.98% (p=0.002 n=6)
Hash/8K-12 1.878Gi ± 1% 1.878Gi ± 1% ~ (p=0.310 n=6)
Hash/1M-12 1.907Gi ± 0% 1.913Gi ± 1% ~ (p=0.485 n=6)
Hash/5M-12 1.911Gi ± 1% 1.904Gi ± 0% ~ (p=0.093 n=6)
Hash/10M-12 1.910Gi ± 0% 1.905Gi ± 0% ~ (p=0.093 n=6)
geomean 1.066Gi 1.032Gi -3.18%
```
(cherry picked from commit abd94ff5b59c86e793fd9bf12187ea6cfd1f3fa1)
(cherry picked from commit 15e81637abf70576a564cf9eecaa9640228afb5b)
Conflicts:
go.mod
https://codeberg.org/forgejo/forgejo/pulls/1581
(cherry picked from commit 5caea2d75aeac78fb306f58a3cf7809d5b70c7f2)
(cherry picked from commit 08da542cce2c1571cedd4183268a903ab581d2e3)
(cherry picked from commit d71a8cc9fb816a3b6562a661286f1d3961821b67)
(cherry picked from commit 63c9fc2bee5b71e6ce3898bbf9b9bce827705acc)
(cherry picked from commit e1db85d48a2de7cff0d438aac81023c4b50cdae4)
(cherry picked from commit 5e86a5d2d1
)
78 lines
2.3 KiB
Go
78 lines
2.3 KiB
Go
// Copyright 2019 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package secret
|
|
|
|
import (
|
|
"crypto/aes"
|
|
"crypto/cipher"
|
|
"crypto/rand"
|
|
"crypto/sha256"
|
|
"encoding/base64"
|
|
"encoding/hex"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
)
|
|
|
|
// AesEncrypt encrypts text and given key with AES.
|
|
func AesEncrypt(key, text []byte) ([]byte, error) {
|
|
block, err := aes.NewCipher(key)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("AesEncrypt invalid key: %v", err)
|
|
}
|
|
b := base64.StdEncoding.EncodeToString(text)
|
|
ciphertext := make([]byte, aes.BlockSize+len(b))
|
|
iv := ciphertext[:aes.BlockSize]
|
|
if _, err = io.ReadFull(rand.Reader, iv); err != nil {
|
|
return nil, fmt.Errorf("AesEncrypt unable to read IV: %w", err)
|
|
}
|
|
cfb := cipher.NewCFBEncrypter(block, iv)
|
|
cfb.XORKeyStream(ciphertext[aes.BlockSize:], []byte(b))
|
|
return ciphertext, nil
|
|
}
|
|
|
|
// AesDecrypt decrypts text and given key with AES.
|
|
func AesDecrypt(key, text []byte) ([]byte, error) {
|
|
block, err := aes.NewCipher(key)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(text) < aes.BlockSize {
|
|
return nil, errors.New("AesDecrypt ciphertext too short")
|
|
}
|
|
iv := text[:aes.BlockSize]
|
|
text = text[aes.BlockSize:]
|
|
cfb := cipher.NewCFBDecrypter(block, iv)
|
|
cfb.XORKeyStream(text, text)
|
|
data, err := base64.StdEncoding.DecodeString(string(text))
|
|
if err != nil {
|
|
return nil, fmt.Errorf("AesDecrypt invalid decrypted base64 string: %w", err)
|
|
}
|
|
return data, nil
|
|
}
|
|
|
|
// EncryptSecret encrypts a string with given key into a hex string
|
|
func EncryptSecret(key, str string) (string, error) {
|
|
keyHash := sha256.Sum256([]byte(key))
|
|
plaintext := []byte(str)
|
|
ciphertext, err := AesEncrypt(keyHash[:], plaintext)
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to encrypt by secret: %w", err)
|
|
}
|
|
return hex.EncodeToString(ciphertext), nil
|
|
}
|
|
|
|
// DecryptSecret decrypts a previously encrypted hex string
|
|
func DecryptSecret(key, cipherHex string) (string, error) {
|
|
keyHash := sha256.Sum256([]byte(key))
|
|
ciphertext, err := hex.DecodeString(cipherHex)
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to decrypt by secret, invalid hex string: %w", err)
|
|
}
|
|
plaintext, err := AesDecrypt(keyHash[:], ciphertext)
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to decrypt by secret, the key (maybe SECRET_KEY?) might be incorrect: %w", err)
|
|
}
|
|
return string(plaintext), nil
|
|
}
|