-
Notifications
You must be signed in to change notification settings - Fork 7
/
crypto.go
98 lines (81 loc) · 2.33 KB
/
crypto.go
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
92
93
94
95
96
97
98
package main
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"crypto/sha256"
"encoding/hex"
"fmt"
"io"
)
// Use non-ASCII bytes as a delimiter.
var delimiter = string(byte(255)) + string(byte(222))
// encryptString takes a password and a plaintext and returns an encrypted byte
// sequence (as a string). It uses AES-GCM with a 12-byte IV (as is
// recommended). The IV is prefixed to the string.
func encryptString(password, plaintext string) string {
// Create a sha256sum hash of the password provided.
hasher := sha256.New()
hasher.Write([]byte(password))
key := hasher.Sum(nil)
// Pad plaintext to be a 16-byte block.
paddingArray := make([]byte, (aes.BlockSize - len(plaintext)%aes.BlockSize))
for char := range paddingArray {
paddingArray[char] = 0x20 // Padding with space character.
}
plaintext = plaintext + string(paddingArray)
if len(plaintext)%aes.BlockSize != 0 {
panic("Plaintext is not a multiple of block size!")
}
// Create cipher block with key.
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
// Generate nonce.
nonce := make([]byte, 12)
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
panic(err.Error())
}
// Create NewGCM cipher.
aesgcm, err := cipher.NewGCM(block)
if err != nil {
panic(err.Error())
}
// Encrypt and seal plaintext.
ciphertext := aesgcm.Seal(nil, nonce, []byte(plaintext), nil)
ciphertext = []byte(fmt.Sprintf("%s%s", nonce, ciphertext))
return string(ciphertext)
}
// decryptString takes a password and a ciphertext and returns a decrypted
// byte sequence (as a string). The function uses typical AES-GCM.
func decryptString(password, ciphertext string) (string, error) {
hasher := sha256.New()
hasher.Write([]byte(password))
key := hasher.Sum(nil)
iv := []byte(ciphertext[:12])
ciphertext = ciphertext[12:]
block, err := aes.NewCipher(key)
if err != nil {
return "", err
}
aesgcm, err := cipher.NewGCM(block)
if err != nil {
return "", err
}
plaintext, err := aesgcm.Open(nil, iv, []byte(ciphertext), nil)
if err != nil {
return "", err
}
return string(plaintext), nil
}
func hexEncode(inputString string) string {
return hex.EncodeToString([]byte(inputString))
}
func hexDecode(inputString string) (string, error) {
result, err := hex.DecodeString(inputString)
if err != nil {
return "", err
}
return string(result), nil
}