aboutsummaryrefslogtreecommitdiff
path: root/inform/crypto.go
diff options
context:
space:
mode:
Diffstat (limited to 'inform/crypto.go')
-rw-r--r--inform/crypto.go88
1 files changed, 88 insertions, 0 deletions
diff --git a/inform/crypto.go b/inform/crypto.go
new file mode 100644
index 0000000..90118c1
--- /dev/null
+++ b/inform/crypto.go
@@ -0,0 +1,88 @@
1package inform
2
3import (
4 "bytes"
5 "crypto/aes"
6 "crypto/cipher"
7 "crypto/rand"
8 "encoding/hex"
9 "errors"
10)
11
12func Pad(src []byte, blockSize int) []byte {
13 padLen := blockSize - (len(src) % blockSize)
14 padText := bytes.Repeat([]byte{byte(padLen)}, padLen)
15 return append(src, padText...)
16}
17
18func Unpad(src []byte, blockSize int) ([]byte, error) {
19 srcLen := len(src)
20 paddingLen := int(src[srcLen-1])
21 if paddingLen >= srcLen || paddingLen > blockSize {
22 return nil, errors.New("Padding size error")
23 }
24 return src[:srcLen-paddingLen], nil
25}
26
27func decodeHexKey(key string) (cipher.Block, error) {
28 decodedKey, err := hex.DecodeString(key)
29 if err != nil {
30 return nil, err
31 }
32
33 block, err := aes.NewCipher(decodedKey)
34 if err != nil {
35 return nil, err
36 }
37
38 return block, nil
39}
40
41func makeAESIV() ([]byte, error) {
42 iv := make([]byte, 16)
43 if _, err := rand.Read(iv); err != nil {
44 return nil, err
45 }
46 return iv, nil
47}
48
49// Returns ciphertext and IV, does not modify payload
50func Encrypt(payload []byte, key string) ([]byte, []byte, error) {
51 ct := make([]byte, len(payload))
52 copy(ct, payload)
53 ct = Pad(ct, aes.BlockSize)
54
55 iv, err := makeAESIV()
56 if err != nil {
57 return nil, nil, err
58 }
59
60 block, err := decodeHexKey(key)
61 if err != nil {
62 return nil, nil, err
63 }
64
65 mode := cipher.NewCBCEncrypter(block, iv)
66 mode.CryptBlocks(ct, ct)
67
68 return ct, iv, nil
69}
70
71func Decrypt(payload, iv []byte, key string) ([]byte, error) {
72 b := make([]byte, len(payload))
73
74 block, err := decodeHexKey(key)
75 if err != nil {
76 return nil, err
77 }
78
79 mode := cipher.NewCBCDecrypter(block, iv)
80 mode.CryptBlocks(b, payload)
81
82 u, err := Unpad(b, aes.BlockSize)
83 if err != nil {
84 return nil, err
85 }
86
87 return u, nil
88}