code.gitea.io/gitea@v1.22.3/modules/secret/secret.go (about) 1 // Copyright 2019 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package secret 5 6 import ( 7 "crypto/aes" 8 "crypto/cipher" 9 "crypto/rand" 10 "crypto/sha256" 11 "encoding/base64" 12 "encoding/hex" 13 "errors" 14 "fmt" 15 "io" 16 ) 17 18 // AesEncrypt encrypts text and given key with AES. 19 func AesEncrypt(key, text []byte) ([]byte, error) { 20 block, err := aes.NewCipher(key) 21 if err != nil { 22 return nil, fmt.Errorf("AesEncrypt invalid key: %v", err) 23 } 24 b := base64.StdEncoding.EncodeToString(text) 25 ciphertext := make([]byte, aes.BlockSize+len(b)) 26 iv := ciphertext[:aes.BlockSize] 27 if _, err = io.ReadFull(rand.Reader, iv); err != nil { 28 return nil, fmt.Errorf("AesEncrypt unable to read IV: %w", err) 29 } 30 cfb := cipher.NewCFBEncrypter(block, iv) 31 cfb.XORKeyStream(ciphertext[aes.BlockSize:], []byte(b)) 32 return ciphertext, nil 33 } 34 35 // AesDecrypt decrypts text and given key with AES. 36 func AesDecrypt(key, text []byte) ([]byte, error) { 37 block, err := aes.NewCipher(key) 38 if err != nil { 39 return nil, err 40 } 41 if len(text) < aes.BlockSize { 42 return nil, errors.New("AesDecrypt ciphertext too short") 43 } 44 iv := text[:aes.BlockSize] 45 text = text[aes.BlockSize:] 46 cfb := cipher.NewCFBDecrypter(block, iv) 47 cfb.XORKeyStream(text, text) 48 data, err := base64.StdEncoding.DecodeString(string(text)) 49 if err != nil { 50 return nil, fmt.Errorf("AesDecrypt invalid decrypted base64 string: %w", err) 51 } 52 return data, nil 53 } 54 55 // EncryptSecret encrypts a string with given key into a hex string 56 func EncryptSecret(key, str string) (string, error) { 57 keyHash := sha256.Sum256([]byte(key)) 58 plaintext := []byte(str) 59 ciphertext, err := AesEncrypt(keyHash[:], plaintext) 60 if err != nil { 61 return "", fmt.Errorf("failed to encrypt by secret: %w", err) 62 } 63 return hex.EncodeToString(ciphertext), nil 64 } 65 66 // DecryptSecret decrypts a previously encrypted hex string 67 func DecryptSecret(key, cipherHex string) (string, error) { 68 keyHash := sha256.Sum256([]byte(key)) 69 ciphertext, err := hex.DecodeString(cipherHex) 70 if err != nil { 71 return "", fmt.Errorf("failed to decrypt by secret, invalid hex string: %w", err) 72 } 73 plaintext, err := AesDecrypt(keyHash[:], ciphertext) 74 if err != nil { 75 return "", fmt.Errorf("failed to decrypt by secret, the key (maybe SECRET_KEY?) might be incorrect: %w", err) 76 } 77 return string(plaintext), nil 78 }