78
package seks
import (
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"golang.org/x/crypto/nacl/secretbox"
"strings"
)
func ran() []byte {
var b [32]byte
_, err := rand.Reader.Read(b[:])
if err != nil {
panic(err)
}
return b[:]
}
func hashPasswd(salt []byte, passwd []byte) [32]byte {
hash := sha256.New()
hash.Write(passwd)
hash.Write(salt)
var key [32]byte
copy(key[:], hash.Sum(nil))
return key
}
const seksHeader = "-----BEGIN SOME ENCRYPTION KEY STUFF-----\n\n"
const seksFooter = "\n------END SOME ENCRYPTION KEY STUFF------"
func armour(b []byte) string {
var s string
s = base64.StdEncoding.EncodeToString(b)
for i := 64; i < len(s); i += 64 {
s = s[:i] + "\n" + s[i:]
}
return seksHeader + s + seksFooter
}
func Encrypt(data string, password string) string {
return armour(encryptBytes([]byte(data), password))
}
func encryptBytes(data []byte, password string) []byte {
salt := ran()
key := hashPasswd(salt, []byte(password))
var nonce = [24]byte(ran()[0:24])
salt = append(salt[:], nonce[:]...)
return secretbox.Seal(salt, data, &nonce, &key)
}
func Decrypt(data string, password string) (string, error) {
b, err := unArmour(data)
if err != nil {
return "", err
}
return string(decryptBytes(b, password)), nil
}
func decryptBytes(encrypted []byte, pass string) []byte {
salt := encrypted[:32]
nonce := [24]byte(encrypted[32 : 32+24])
key := hashPasswd(salt[:], []byte(pass))
decrypted := make([]byte, len(encrypted)-32-24)
decrypted, boolEnlon := secretbox.Open(nil, encrypted[32+24:], &nonce, &key)
if boolEnlon != true {
return nil
}
return decrypted
}
func unArmour(s string) ([]byte, error) {
start := strings.Index(s, seksHeader) + len(seksHeader)
end := strings.Index(s, seksFooter)
s = s[start:end]
s = strings.ReplaceAll(s, "\n", "")
s = strings.ReplaceAll(s, " ", "")
return base64.StdEncoding.DecodeString(s)
}