-
Notifications
You must be signed in to change notification settings - Fork 2
/
pbewithmd5anddes.go
105 lines (83 loc) · 2.81 KB
/
pbewithmd5anddes.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
99
100
101
102
103
104
105
package passwordbasedencryption
import (
"strings"
"encoding/base64"
"crypto/cipher"
"crypto/des"
"crypto/md5"
"crypto/rand"
)
func getDerivedKey(password string, salt string, count int) ([]byte, []byte) {
key := md5.Sum([]byte(password + salt))
for i := 0; i < count - 1; i++ {
key = md5.Sum(key[:])
}
return key[:8], key[8:]
}
func Encrypt(password string, obtenationIterations int, plainText string) (string, error) {
salt := make([]byte, 8)
_, err := rand.Read(salt)
if err != nil {
return "", err
}
encText, err := doEncrypt(password, plainText, salt, obtenationIterations)
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(append(salt, encText...)), nil
}
func Decrypt(password string, obtenationIterations int, cipherText string) (string, error) {
msgBytes, err := base64.StdEncoding.DecodeString(cipherText)
if err != nil {
return "", err
}
salt := msgBytes[:8]
encText := msgBytes[8:]
return doDecrypt(password, encText, salt, obtenationIterations)
}
func EncryptWithFixedSalt(password string, obtenationIterations int, plainText string, fixedSalt string) (string, error) {
salt := make([]byte, 8)
copy(salt[:], fixedSalt)
encText, err := doEncrypt(password, plainText, salt, obtenationIterations)
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(encText), nil
}
func DecryptWithFixedSalt(password string, obtenationIterations int, cipherText string, fixedSalt string) (string, error) {
msgBytes, err := base64.StdEncoding.DecodeString(cipherText)
if err != nil {
return "", err
}
salt := make([]byte, 8)
copy(salt[:], fixedSalt)
encText := msgBytes[:]
return doDecrypt(password, encText, salt, obtenationIterations)
}
func doEncrypt(password, plainText string, salt []byte, obtenationIterations int) ([]byte, error) {
padNum := byte(8 - len(plainText) % 8)
for i := byte(0); i < padNum; i++ {
plainText += string(padNum)
}
dk, iv := getDerivedKey(password, string(salt), obtenationIterations)
block,err := des.NewCipher(dk)
if err != nil {
return nil, err
}
encrypter := cipher.NewCBCEncrypter(block, iv)
encrypted := make([]byte, len(plainText))
encrypter.CryptBlocks(encrypted, []byte(plainText))
return encrypted, nil
}
func doDecrypt(password string, encText, salt []byte, obtenationIterations int) (string, error) {
dk, iv := getDerivedKey(password, string(salt), obtenationIterations)
block, err := des.NewCipher(dk)
if err != nil {
return "", err
}
decrypter := cipher.NewCBCDecrypter(block, iv)
decrypted := make([]byte, len(encText))
decrypter.CryptBlocks(decrypted, encText)
decryptedString := strings.TrimRight(string(decrypted), "\x01\x02\x03\x04\x05\x06\x07\x08")
return decryptedString, nil
}