made pub key stuff uwu
sophuwu sophie@skisiel.com
Wed, 24 Jul 2024 00:06:14 +0200
2 files changed,
115 insertions(+),
53 deletions(-)
M
seks.go
→
seks.go
@@ -2,27 +2,41 @@ package seks
import ( "crypto/rand" - "crypto/sha256" "encoding/base64" - "golang.org/x/crypto/nacl/secretbox" + "encoding/hex" + "errors" + "golang.org/x/crypto/nacl/box" "strings" ) -func ran() []byte { - var b [32]byte +func KeyGen() (string, string) { + pub, priv, err := box.GenerateKey(rand.Reader) + if err != nil { + return "", "" + } + pubs := "public-key-" + hex.EncodeToString(pub[:]) + privs := "SECRET-KEY-" + strings.ToUpper(hex.EncodeToString(priv[:])) + return pubs, privs +} + +func ReadKey(s string) ([32]byte, error) { + s = strings.ToLower(s) + s = strings.TrimPrefix(s, "public-key-") + s = strings.TrimPrefix(s, "secret-key-") + b, err := hex.DecodeString(s) + if err != nil { + return [32]byte{}, errors.New("invalid key") + } + return [32]byte(b[0:32]), nil +} + +func ran() [24]byte { + var b [24]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 + return b } const seksHeader = "-----BEGIN SOME ENCRYPTION KEY STUFF-----\n\n"@@ -37,42 +51,82 @@ }
return seksHeader + s + seksFooter } -func Encrypt(data string, password string) string { - return armour(encryptBytes([]byte(data), password)) +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) } -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 EncryptString(data string, toPubKey string, fromPrivKey string) (string, error) { + b, err := EncryptBytes([]byte(data), toPubKey, fromPrivKey) + if err != nil { + return "", err + } + return armour(b), nil } -func Decrypt(data string, password string) (string, error) { +func EncryptArmour(b []byte, toPubKey string, fromPrivKey string) ([]byte, error) { + b, err := EncryptBytes(b, toPubKey, fromPrivKey) + if err != nil { + return nil, err + } + return []byte(armour(b)), nil +} + +func EncryptBytes(data []byte, toPubKey string, fromPrivKey string) ([]byte, error) { + var nonce = ran() + pubKey, err := ReadKey(toPubKey) + if err != nil { + return nil, err + } + privKey, err := ReadKey(fromPrivKey) + if err != nil { + return nil, err + } + var out []byte = nonce[:] + return box.Seal(out, data, &nonce, &pubKey, &privKey), nil +} + +func DecryptString(data string, fromPubKey string, toPrivKey string) (string, error) { b, err := unArmour(data) if err != nil { return "", err } - return string(decryptBytes(b, password)), nil + out, err := DecryptBytes(b, fromPubKey, toPrivKey) + if err != nil { + return "", err + } + return string(out), 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 +func DecryptBytes(data []byte, fromPubKey string, toPrivKey string) ([]byte, error) { + nonce := [24]byte(data[0:24]) + pubKey, err := ReadKey(fromPubKey) + if err != nil { + return nil, err + } + privKey, err := ReadKey(toPrivKey) + if err != nil { + return nil, err } - return decrypted + out, ok := box.Open(nil, data[24:], &nonce, &pubKey, &privKey) + if !ok { + return nil, errors.New("decryption failed") + } + return out, nil } -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) +func DecryptArmour(data []byte, fromPubKey string, toPrivKey string) ([]byte, error) { + b, err := unArmour(string(data)) + if err != nil { + return nil, err + } + out, err := DecryptBytes(b, fromPubKey, toPrivKey) + if err != nil { + return nil, err + } + return out, nil }
M
test/test.go
→
test/test.go
@@ -7,23 +7,31 @@ "sophuwu.site/seks"
) func main() { - if len(os.Args) < 4 { - os.Exit(1) + if len(os.Args) > 1 && os.Args[1] == "gen" { + pub, priv := seks.KeyGen() + fmt.Println(pub) + fmt.Println(priv) + return } - b, e := os.ReadFile(os.Args[3]) - if e != nil { - fmt.Println(e) - os.Exit(1) + if len(os.Args) != 5 { + return + } + keys := make(map[byte]string) + keys[os.Args[2][0]] = os.Args[2] + keys[os.Args[3][0]] = os.Args[3] + b, err := os.ReadFile(os.Args[4]) + if err != nil { + fmt.Println(err) + return } if os.Args[1] == "e" { - fmt.Println(seks.Encrypt(string(b), os.Args[2])) + b, err = seks.EncryptArmour(b, keys['p'], keys['S']) + } else if os.Args[1] == "d" { + b, err = seks.DecryptArmour(b, keys['p'], keys['S']) } - if os.Args[1] == "d" { - s, err := seks.Decrypt(string(b), os.Args[2]) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - fmt.Println(s) + if err != nil { + fmt.Println(err) + return } + fmt.Println(string(b)) }