Personal book of passwords

security.go 1.7KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. package main
  2. import (
  3. "crypto/aes"
  4. "crypto/cipher"
  5. "crypto/rand"
  6. "encoding/base64"
  7. "errors"
  8. "io"
  9. "os"
  10. )
  11. func encodeBase64(data []byte) string {
  12. return base64.StdEncoding.EncodeToString(data)
  13. }
  14. func decodeBase64(data []byte) []byte {
  15. b, _ := base64.StdEncoding.DecodeString(string(data))
  16. return b
  17. }
  18. func getLocalKey() string {
  19. env := os.Getenv("ENIGMA_KEY")
  20. if env == "" {
  21. env = "thebrownfoxjumpedoverthefence"
  22. }
  23. return env
  24. }
  25. func getSizedKey(key string) string {
  26. // Get the correct key length
  27. l := len(key)
  28. if l < 16 {
  29. for i := 0; i < 16-l; i++ {
  30. key += "."
  31. }
  32. } else if l < 24 {
  33. for i := 0; i < 24-l; i++ {
  34. key += "."
  35. }
  36. } else if l < 32 {
  37. for i := 0; i < 32-l; i++ {
  38. key += "."
  39. }
  40. } else {
  41. key = key[:32]
  42. }
  43. return key
  44. }
  45. // Encrypt the password book
  46. func encrypt(text, passphrase string) ([]byte, error) {
  47. key := []byte(getSizedKey(passphrase))
  48. block, err := aes.NewCipher(key)
  49. if err != nil {
  50. return nil, err
  51. }
  52. cipherText := make([]byte, aes.BlockSize+len(text))
  53. iv := cipherText[:aes.BlockSize]
  54. if _, err := io.ReadFull(rand.Reader, iv); err != nil {
  55. return nil, err
  56. }
  57. encrypter := cipher.NewCFBEncrypter(block, iv)
  58. encrypter.XORKeyStream(cipherText[aes.BlockSize:], []byte(text))
  59. return cipherText, nil
  60. }
  61. // Decrypt the password book
  62. func decrypt(text []byte, passphrase string) ([]byte, error) {
  63. key := []byte(getSizedKey(passphrase))
  64. block, err := aes.NewCipher(key)
  65. if err != nil {
  66. return nil, err
  67. }
  68. if len(text) < aes.BlockSize {
  69. return nil, errors.New("Cipher text too short")
  70. }
  71. iv := text[:aes.BlockSize]
  72. data := text[aes.BlockSize:]
  73. decrypter := cipher.NewCFBDecrypter(block, iv)
  74. decrypter.XORKeyStream(data, data)
  75. return data, nil
  76. }