stringcrypt.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /*
  2. * Public Domain Software
  3. *
  4. * I (Matthias Ladkau) am the author of the source code in this file.
  5. * I have placed the source code in this file in the public domain.
  6. *
  7. * For further information see: http://creativecommons.org/publicdomain/zero/1.0/
  8. */
  9. package cryptutil
  10. import (
  11. "crypto/aes"
  12. "crypto/cipher"
  13. "crypto/rand"
  14. "crypto/sha256"
  15. "encoding/base64"
  16. "fmt"
  17. "io"
  18. )
  19. /*
  20. EncryptString encrypts a given string using AES (cfb mode).
  21. */
  22. func EncryptString(passphrase, text string) (string, error) {
  23. var ret []byte
  24. // Create a new cipher with the given key
  25. key := sha256.Sum256([]byte(passphrase))
  26. block, err := aes.NewCipher((&key)[:])
  27. if err == nil {
  28. // Base64 encode the string
  29. b := base64.StdEncoding.EncodeToString([]byte(text))
  30. ciphertext := make([]byte, aes.BlockSize+len(b))
  31. // Create the initialization vector using random numbers
  32. iv := ciphertext[:aes.BlockSize]
  33. if _, err = io.ReadFull(rand.Reader, iv); err == nil {
  34. // Do the encryption
  35. cfb := cipher.NewCFBEncrypter(block, iv)
  36. cfb.XORKeyStream(ciphertext[aes.BlockSize:], []byte(b))
  37. ret = ciphertext
  38. }
  39. }
  40. return string(ret), err
  41. }
  42. /*
  43. DecryptString decrypts a given string using AES (cfb mode).
  44. */
  45. func DecryptString(passphrase, text string) (string, error) {
  46. var ret []byte
  47. // Check encrypted text
  48. if len(text) < aes.BlockSize {
  49. return "", fmt.Errorf("Ciphertext is too short - must be at least: %v", aes.BlockSize)
  50. }
  51. // Create a new cipher with the given key
  52. key := sha256.Sum256([]byte(passphrase))
  53. block, err := aes.NewCipher((&key)[:])
  54. if err == nil {
  55. // Separate initialization vector and actual encrypted text
  56. iv := text[:aes.BlockSize]
  57. text = text[aes.BlockSize:]
  58. // Do the decryption
  59. cfb := cipher.NewCFBDecrypter(block, []byte(iv))
  60. ret = []byte(text) // Reuse text buffer
  61. cfb.XORKeyStream(ret, []byte(text))
  62. // Decode text from base64
  63. ret, err = base64.StdEncoding.DecodeString(string(ret))
  64. if err != nil {
  65. // Return a proper error if something went wrong
  66. ret = nil
  67. err = fmt.Errorf("Could not decrypt data")
  68. }
  69. }
  70. return string(ret), err
  71. }