encryption.go 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. package main
  2. import (
  3. "crypto/aes"
  4. "crypto/cipher"
  5. "crypto/rand"
  6. )
  7. func encrypt(plaintext, key []byte) ([]byte, error) {
  8. block, err := aes.NewCipher(key)
  9. if err != nil {
  10. return []byte{}, err
  11. }
  12. iv := make([]byte, aes.BlockSize)
  13. rand.Read(iv)
  14. plaintextPadded := pad(plaintext)
  15. encrypted := make([]byte, len(plaintextPadded))
  16. mode := cipher.NewCBCEncrypter(block, iv)
  17. mode.CryptBlocks(encrypted, plaintextPadded)
  18. return append(iv, encrypted...), nil
  19. }
  20. func decrypt(encryptedIVandData, key []byte) ([]byte, error) {
  21. block, err := aes.NewCipher(key)
  22. if err != nil {
  23. return []byte{}, err
  24. }
  25. iv := encryptedIVandData[0:aes.BlockSize]
  26. encrypted := encryptedIVandData[aes.BlockSize:]
  27. mode := cipher.NewCBCDecrypter(block, iv)
  28. plaintextPadded := make([]byte, len(encrypted))
  29. mode.CryptBlocks(plaintextPadded, encrypted)
  30. plaintext := unpad(plaintextPadded)
  31. return plaintext, nil
  32. }
  33. func unpad(in []byte) []byte {
  34. if len(in) == 0 {
  35. return nil
  36. }
  37. padding := in[len(in)-1]
  38. if int(padding) > len(in) || padding > aes.BlockSize {
  39. return nil
  40. } else if padding == 0 {
  41. return nil
  42. }
  43. for i := len(in) - 1; i > len(in)-int(padding)-1; i-- {
  44. if in[i] != padding {
  45. return nil
  46. }
  47. }
  48. return in[:len(in)-int(padding)]
  49. }
  50. func pad(in []byte) []byte {
  51. padding := aes.BlockSize - (len(in) % aes.BlockSize)
  52. for i := 0; i < padding; i++ {
  53. in = append(in, byte(padding))
  54. }
  55. return in
  56. }