Newer
Older
package securitymdl
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/constantmdl"
"corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/errormdl"
"corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/loggermdl"
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
)
// SetSecurityConfig will set security key and initializationVector
func SetSecurityConfig(secKey []byte, initializationVector string) {
loggermdl.LogDebug("SetSecurityConfig Started")
SetIV(initializationVector)
SetSecurityKey(secKey)
loggermdl.LogDebug("SetSecurityConfig Ended")
}
// SetIV will set initializationVector
func SetIV(initializationVector string) {
loggermdl.LogDebug("SetIV Started")
if initializationVector != "" {
IV = initializationVector
}
loggermdl.LogDebug("SetIV Ended")
}
// SetSecurityKey will set Security key
func SetSecurityKey(secKey []byte) {
loggermdl.LogDebug("SetSecurityKey Started")
if secKey != nil && len(secKey) != 1 {
securityKey = secKey
}
loggermdl.LogDebug("SetSecurityKey Ended")
}
//AESEncrypt Encrypts given text
func AESEncrypt(plainText, key []byte) ([]byte, error) {
loggermdl.LogDebug("AESEncrypt Started")
block, newCipherErr := aes.NewCipher(key)
if errormdl.CheckErr(newCipherErr) != nil {
loggermdl.LogError("error occured while calling aes.NewCipher() : ", errormdl.CheckErr(newCipherErr))
return nil, errormdl.CheckErr(newCipherErr)
}
padding := block.BlockSize() - len(plainText)%block.BlockSize()
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
plainText = append(plainText, padtext...)
cipherText := make([]byte, len(plainText))
ivBytes := []byte(IV)
if ivBytes == nil || len(ivBytes) < 1 || len(ivBytes) != block.BlockSize() {
loggermdl.LogError("IV length must equal block size")
return nil, errormdl.Wrap("IV length must equal block size")
}
cbc := cipher.NewCBCEncrypter(block, ivBytes)
cbc.CryptBlocks(cipherText, plainText)
encodedData := make([]byte, base64.StdEncoding.EncodedLen(len(plainText)))
base64.StdEncoding.Encode(encodedData, cipherText)
loggermdl.LogDebug("AESEncrypt Started")
return encodedData, nil
}
//AESDecrypt Decrypts given cipher text
func AESDecrypt(encodedData, key []byte) ([]byte, error) {
loggermdl.LogDebug("AESDecrypt Started")
decodedData := make([]byte, base64.StdEncoding.DecodedLen(len(encodedData)))
n, decoreErr := base64.StdEncoding.Decode(decodedData, encodedData)
if errormdl.CheckErr(decoreErr) != nil {
loggermdl.LogError("error occured while calling base64.StdEncoding.Decode() : ", errormdl.CheckErr(decoreErr))
return nil, errormdl.CheckErr(decoreErr)
}
cipherText := decodedData[:n]
block, newCipherErr := aes.NewCipher(key)
if errormdl.CheckErr1(newCipherErr) != nil {
loggermdl.LogError("error occured while calling aes.NewCipher : ", errormdl.CheckErr1(newCipherErr))
return nil, errormdl.CheckErr1(newCipherErr)
}
ivBytes := []byte(IV)
if ivBytes == nil || len(ivBytes) < 1 || len(ivBytes) != block.BlockSize() {
loggermdl.LogError("IV length must equal block size ")
return nil, errormdl.Wrap("IV length must equal block size ")
}
cbc := cipher.NewCBCDecrypter(block, []byte(IV))
calculatedCipherSize := len(cipherText) % cbc.BlockSize()
if errormdl.CheckInt1(calculatedCipherSize) != 0 {
loggermdl.LogError("crypto/cipher: input not full blocks")
return nil, errormdl.Wrap("crypto/cipher: input not full blocks")
}
cbc.CryptBlocks(cipherText, cipherText)
length := len(cipherText)
if errormdl.CheckInt(length) < 1 {
loggermdl.LogError("length of cipherText is less than 1")
return nil, errormdl.Wrap("length of cipherText is less than 1")
}
unpadding := int(cipherText[length-1])
difference := length - unpadding
if errormdl.CheckInt2(difference) < 0 {
return nil, errormdl.Wrap("length of (length - unpadding) is less than 0")
}
loggermdl.LogDebug("AESDecrypt Ended")
return cipherText[:(length - unpadding)], nil
}
// //AESEncryptDefault method to encrypt with default config (securityKey)
// func AESEncryptDefault(plainText []byte) ([]byte, error) {
// loggermdl.LogDebug("AESEncryptDefault Started")
// compressedText, compressionError := Compress(plainText)
// if compressionError != nil {
// return plainText, compressionError
// }
// loggermdl.LogDebug("AESEncryptDefault Started")
// return AESEncrypt(compressedText, securityKey)
// }
// // AESDecryptDefault method to decrypt with default config (securityKey)
// func AESDecryptDefault(encodedData []byte) ([]byte, error) {
// loggermdl.LogDebug("AESDecryptDefault Started")
// compressedText, decryptionError := AESDecrypt(encodedData, securityKey)
// if decryptionError != nil {
// return encodedData, decryptionError
// }
// byteArray, err := Decompress(compressedText)
// if err != nil {
// }
// loggermdl.LogDebug("AESDecryptDefault Started")
// return byteArray, nil
// }
// CreateSecurityKey generates random string of given length
func CreateSecurityKey(keyLength int) (string, error) {
if keyLength <= constantmdl.MAX_RANDOM_STRING_LENGTH {
seededRand := rand.New(rand.NewSource(time.Now().UnixNano()))
b := make([]byte, keyLength)
for i := range b {
b[i] = constantmdl.CharSet[seededRand.Intn(keyLength)]
}
return string(b), nil
}
return "", errormdl.Wrap("length should be less than 256 bytes (2048 bits)")
}
// SaltPassword Salt using bcrypt creates saltedString of given string,it generates new saltedString each time for the same input
func SaltPassword(password string) (string, error) {
hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.MinCost)
if errormdl.CheckErr(err) != nil {
loggermdl.LogError("error occured while calling bcrypt.GenerateFromPassword() : ", errormdl.CheckErr(err))
return "", errormdl.CheckErr(err)
}
return string(hash), nil
}
// CheckPasswordHash - compares hashed password with its possible plaintext equivalent. Returns true on match, or an false on mismatch.
func CheckPasswordHash(hashedPassword, password string) bool {
err := bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(password))
return err == nil
}