-
Notifications
You must be signed in to change notification settings - Fork 63
Expand file tree
/
Copy pathaes_cbc_cryptor.go
More file actions
91 lines (74 loc) · 2.04 KB
/
Copy pathaes_cbc_cryptor.go
File metadata and controls
91 lines (74 loc) · 2.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package crypto
import (
"crypto/aes"
"crypto/cipher"
"crypto/sha256"
"errors"
"fmt"
"io"
)
type aesCbcCryptor struct {
block cipher.Block
}
func NewAesCbcCryptor(cipherKey string) (ExtendedCryptor, error) {
block, e := aesCipher(cipherKey)
if e != nil {
return nil, e
}
return &aesCbcCryptor{
block: block,
}, nil
}
var crivId = "ACRH"
func (c *aesCbcCryptor) Id() string {
return crivId
}
func (c *aesCbcCryptor) Encrypt(message []byte) (*EncryptedData, error) {
message = padWithPKCS7(message)
iv := generateIV(aes.BlockSize)
blockmode := cipher.NewCBCEncrypter(c.block, iv)
encryptedBytes := make([]byte, len(message))
blockmode.CryptBlocks(encryptedBytes, message)
return &EncryptedData{
Metadata: iv,
Data: encryptedBytes,
}, nil
}
func (c *aesCbcCryptor) Decrypt(encryptedData *EncryptedData) (r []byte, e error) {
decrypter := cipher.NewCBCDecrypter(c.block, encryptedData.Metadata)
//to handle decryption errors
defer func() {
if rec := recover(); rec != nil {
r, e = nil, fmt.Errorf("decrypt error: %s", rec)
}
}()
decrypted := make([]byte, len(encryptedData.Data))
decrypter.CryptBlocks(decrypted, encryptedData.Data)
val, err := unpadPKCS7(decrypted)
if err != nil {
return nil, fmt.Errorf("decrypt error: %s", err)
}
return val, nil
}
func (c *aesCbcCryptor) EncryptStream(reader io.Reader) (*EncryptedStreamData, error) {
iv := generateIV(aes.BlockSize)
return &EncryptedStreamData{
Metadata: iv,
Reader: newBlockModeEncryptingReader(reader, cipher.NewCBCEncrypter(c.block, iv)),
}, nil
}
func (c *aesCbcCryptor) DecryptStream(encryptedData *EncryptedStreamData) (io.Reader, error) {
if encryptedData.Metadata == nil {
return nil, errors.New("missing metadata")
}
return newBlockModeDecryptingReader(encryptedData.Reader, cipher.NewCBCDecrypter(c.block, encryptedData.Metadata)), nil
}
func aesCipher(cipherKey string) (cipher.Block, error) {
hash := sha256.New()
hash.Write([]byte(cipherKey))
block, err := aes.NewCipher(hash.Sum(nil))
if err != nil {
return nil, err
}
return block, nil
}