You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

secret.go 2.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. // Copyright 2019 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package secret
  5. import (
  6. "crypto/aes"
  7. "crypto/cipher"
  8. "crypto/rand"
  9. "crypto/sha256"
  10. "encoding/base64"
  11. "encoding/hex"
  12. "errors"
  13. "io"
  14. "code.gitea.io/gitea/modules/util"
  15. )
  16. // New creates a new secret
  17. func New() (string, error) {
  18. return NewWithLength(44)
  19. }
  20. // NewWithLength creates a new secret for a given length
  21. func NewWithLength(length int64) (string, error) {
  22. return util.RandomString(length)
  23. }
  24. // AesEncrypt encrypts text and given key with AES.
  25. func AesEncrypt(key, text []byte) ([]byte, error) {
  26. block, err := aes.NewCipher(key)
  27. if err != nil {
  28. return nil, err
  29. }
  30. b := base64.StdEncoding.EncodeToString(text)
  31. ciphertext := make([]byte, aes.BlockSize+len(b))
  32. iv := ciphertext[:aes.BlockSize]
  33. if _, err := io.ReadFull(rand.Reader, iv); err != nil {
  34. return nil, err
  35. }
  36. cfb := cipher.NewCFBEncrypter(block, iv)
  37. cfb.XORKeyStream(ciphertext[aes.BlockSize:], []byte(b))
  38. return ciphertext, nil
  39. }
  40. // AesDecrypt decrypts text and given key with AES.
  41. func AesDecrypt(key, text []byte) ([]byte, error) {
  42. block, err := aes.NewCipher(key)
  43. if err != nil {
  44. return nil, err
  45. }
  46. if len(text) < aes.BlockSize {
  47. return nil, errors.New("ciphertext too short")
  48. }
  49. iv := text[:aes.BlockSize]
  50. text = text[aes.BlockSize:]
  51. cfb := cipher.NewCFBDecrypter(block, iv)
  52. cfb.XORKeyStream(text, text)
  53. data, err := base64.StdEncoding.DecodeString(string(text))
  54. if err != nil {
  55. return nil, err
  56. }
  57. return data, nil
  58. }
  59. // EncryptSecret encrypts a string with given key into a hex string
  60. func EncryptSecret(key string, str string) (string, error) {
  61. keyHash := sha256.Sum256([]byte(key))
  62. plaintext := []byte(str)
  63. ciphertext, err := AesEncrypt(keyHash[:], plaintext)
  64. if err != nil {
  65. return "", err
  66. }
  67. return hex.EncodeToString(ciphertext), nil
  68. }
  69. // DecryptSecret decrypts a previously encrypted hex string
  70. func DecryptSecret(key string, cipherhex string) (string, error) {
  71. keyHash := sha256.Sum256([]byte(key))
  72. ciphertext, err := hex.DecodeString(cipherhex)
  73. if err != nil {
  74. return "", err
  75. }
  76. plaintext, err := AesDecrypt(keyHash[:], ciphertext)
  77. if err != nil {
  78. return "", err
  79. }
  80. return string(plaintext), nil
  81. }