This repository has been archived on 2021-08-10. You can view files and clone it, but cannot push or open issues or pull requests.
gtools/encrypt/encrypt.go

104 lines
2.2 KiB
Go

package encrypt
import (
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"fmt"
"io/ioutil"
"os"
"github.com/OneOfOne/xxhash"
)
type Encrypt struct {
PrivateKey *rsa.PrivateKey
}
func LoadKey(path string, keygen bool) (encrypt *Encrypt, err error) {
var privateKey *rsa.PrivateKey
if keygen {
privateKey, err = generateKey()
if err != nil {
return nil, err
}
if err := writeKeyToFile(path, privateKey); err != nil {
return nil, err
}
} else {
privateKey, err = readPrivateKey(path)
if err != nil {
return nil, err
}
}
return &Encrypt{
PrivateKey: privateKey,
}, nil
}
func generateKey() (*rsa.PrivateKey, error) {
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return nil, err
}
return privateKey, nil
}
func writeKeyToFile(path string, privateKey *rsa.PrivateKey) error {
pemdata := pem.EncodeToMemory(
&pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(privateKey),
},
)
if _, err := os.Stat(path); os.IsNotExist(err) {
if err := ioutil.WriteFile(path, pemdata, 0640); err != nil {
return err
}
return nil
}
return fmt.Errorf("private key file %s already exists", path)
}
func readPrivateKey(path string) (*rsa.PrivateKey, error) {
file, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
pemdata, _ := pem.Decode(file)
privateKey, err := x509.ParsePKCS1PrivateKey(pemdata.Bytes)
if err != nil {
return nil, err
}
return privateKey, nil
}
func (enc *Encrypt) Encrypt(secretMessage string) (string, error) {
ciphertext, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, &enc.PrivateKey.PublicKey, []byte(secretMessage), []byte("OAEP Encrypted"))
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(ciphertext), nil
}
func (enc *Encrypt) Decrypt(cipherText string) (string, error) {
ct, err := base64.StdEncoding.DecodeString(cipherText)
if err != nil {
return "", err
}
plaintext, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, enc.PrivateKey, ct, []byte("OAEP Encrypted"))
if err != nil {
return "", err
}
return string(plaintext), nil
}
func Hash(key []byte) uint64 {
hash := xxhash.New64()
hash.Write(key)
return hash.Sum64()
}