You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
2.7 KiB
Go
104 lines
2.7 KiB
Go
package libs
|
|
|
|
import (
|
|
"crypto/cipher"
|
|
"crypto/des"
|
|
"crypto/md5"
|
|
"crypto/rand"
|
|
"encoding/base64"
|
|
"strings"
|
|
)
|
|
|
|
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
|
|
}
|