78 lines
1.7 KiB
Go
78 lines
1.7 KiB
Go
package crypto
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/aes"
|
|
"crypto/cipher"
|
|
"crypto/rand"
|
|
"crypto/sha512"
|
|
"errors"
|
|
"golang.org/x/crypto/pbkdf2"
|
|
"io"
|
|
)
|
|
|
|
var secret = []byte("dazyunsecretkeysforuserstenx20141019generatedKey")
|
|
var Undecryptable = errors.New("undecryptable input")
|
|
|
|
func key(salt []byte) []byte {
|
|
return pbkdf2.Key(secret, salt, 2145, 32, sha512.New)
|
|
}
|
|
|
|
func randBytes(length int) (bytes []byte, err error) {
|
|
bytes = make([]byte, length)
|
|
if _, err = io.ReadFull(rand.Reader, bytes); err != nil {
|
|
return
|
|
}
|
|
return
|
|
}
|
|
|
|
func AEADEncrypt(content []byte) (encrypted []byte, err error) {
|
|
var salt []byte
|
|
if salt, err = randBytes(64); err != nil {
|
|
return
|
|
}
|
|
var block cipher.Block
|
|
if block, err = aes.NewCipher(key(salt)); err != nil {
|
|
return
|
|
}
|
|
var iv []byte
|
|
if iv, err = randBytes(12); err != nil {
|
|
return
|
|
}
|
|
if _, err = io.ReadFull(rand.Reader, iv); err != nil {
|
|
return
|
|
}
|
|
var aes256gcm cipher.AEAD
|
|
if aes256gcm, err = cipher.NewGCM(block); err != nil {
|
|
return
|
|
}
|
|
withTag := aes256gcm.Seal(nil, iv, content, nil)
|
|
encryptedLen := len(withTag) - 16
|
|
withoutTag := withTag[:encryptedLen]
|
|
tag := withTag[encryptedLen:]
|
|
encrypted = bytes.Join([][]byte{salt, iv, tag, withoutTag}, []byte{})
|
|
return
|
|
}
|
|
|
|
func AEADDecrypt(encrypted []byte) (content []byte, err error) {
|
|
if len(encrypted) <= 92 {
|
|
err = Undecryptable
|
|
return
|
|
}
|
|
salt := encrypted[:64]
|
|
iv := encrypted[64:76]
|
|
tag := encrypted[76:92]
|
|
withoutTag := encrypted[92:]
|
|
withTag := bytes.Join([][]byte{withoutTag, tag}, []byte{})
|
|
var block cipher.Block
|
|
if block, err = aes.NewCipher(key(salt)); err != nil {
|
|
return
|
|
}
|
|
var aes256gcm cipher.AEAD
|
|
if aes256gcm, err = cipher.NewGCM(block); err != nil {
|
|
return
|
|
}
|
|
content, err = aes256gcm.Open(nil, iv, withTag, nil)
|
|
return
|
|
}
|