-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathengine_aes.go
More file actions
85 lines (67 loc) · 2.22 KB
/
engine_aes.go
File metadata and controls
85 lines (67 loc) · 2.22 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
package encryption
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"fmt"
"io"
)
type AesEngine struct {
secretResolver SecretResolver
}
func NewAesEngine(secretResolver SecretResolver) *AesEngine {
return &AesEngine{
secretResolver: secretResolver,
}
}
func (a *AesEngine) newGcm() ([]byte, cipher.AEAD, error) {
// resolve the secret from the abstract secret resolver
secret, errSecret := a.secretResolver.GetPlainSecret()
if errSecret != nil {
return nil, nil, fmt.Errorf("could not resolve secret: %s", errSecret.Error())
}
// create the new cipher
newCipher, errCipher := aes.NewCipher(secret)
if errCipher != nil {
return nil, nil, fmt.Errorf("could not create cipher instance from secret: %s", errCipher.Error())
}
// create a gcm instance from cipher instance
newGcm, errGcm := cipher.NewGCM(newCipher)
if errGcm != nil {
return nil, nil, fmt.Errorf("could not create gcm from cipher instance: %s", errGcm.Error())
}
// creates a new byte array the size of the nonce
// which must be passed to Seal
nonce := make([]byte, newGcm.NonceSize())
// populates our nonce with a cryptographically secure
// random sequence
if _, errCreateNonce := io.ReadFull(rand.Reader, nonce); errCreateNonce != nil {
return nil, nil, fmt.Errorf("could not create nonce from gcm instance: %s", errCreateNonce.Error())
}
// return the new gcm
return nonce, newGcm, nil
}
func (a *AesEngine) EncodeValue(plainValue string) (encodedValue string, err error) {
nonce, gcm, errGcm := a.newGcm()
if errGcm != nil {
return "", errGcm
}
return string(gcm.Seal(nonce, nonce, []byte(plainValue), nil)), nil
}
func (a *AesEngine) DecodeValue(encodedValue string) (decodedValue string, err error) {
_, gcm, errGcm := a.newGcm()
if errGcm != nil {
return "", errGcm
}
nonceSize := gcm.NonceSize()
encodedValueBytes := []byte(encodedValue)
if len(encodedValueBytes) < nonceSize {
return "", fmt.Errorf("encoded value is smaller than nonce size")
}
nonce, cipherText := encodedValueBytes[:nonceSize], encodedValueBytes[nonceSize:]
plainBytes, errOpen := gcm.Open(nil, nonce, cipherText, nil)
if errOpen != nil {
return "", fmt.Errorf("could not open via gcm: %s", errOpen.Error())
}
return string(plainBytes), nil
}