From 2516b41597816b9abdd42d4e3ff4f89d748b1f19 Mon Sep 17 00:00:00 2001 From: ycc Date: Sun, 20 Nov 2022 17:52:27 +0100 Subject: [PATCH] New functions for flutter openpgp compatibility --- asymcrypt.go | 107 ++++++++++++++++++++++++++++++++++++++++++++++ asymcrypt_test.go | 74 ++++++++++++++++++++++++++++++++ 2 files changed, 181 insertions(+) diff --git a/asymcrypt.go b/asymcrypt.go index 19bc333..7b2c2ce 100644 --- a/asymcrypt.go +++ b/asymcrypt.go @@ -192,3 +192,110 @@ func createPublicKeyRing(publicKey string) (*crypto.KeyRing, error) { return publicKeyRing, nil } + +func AsymEncryptAndSign2(PublicEncryptionKey string, PrivateSignatureKey string, data []byte) ([]byte, []byte, error) { + pub, err := base64.StdEncoding.DecodeString(PublicEncryptionKey) + if err != nil { + log.Error().Msg("Message encryption and sign b64 failed") + } + priv, err := base64.StdEncoding.DecodeString(PrivateSignatureKey) + if err != nil { + log.Error().Msg("Message encryption and sign b64 failed") + } + ciphertext, signature, err := encryptAndSignMessage(string(pub), string(priv), crypto.NewPlainMessage(data)) + if err != nil { + log.Error().Msg("Message encryption failed") + return nil, nil, err + } + return ciphertext.GetBinary(), signature, err +} + +func AsymDecryptAndCheck2(MyPrivateEncryptionKey string, MyContactPublicKey string, data []byte, Signature []byte) (DecryptedMessage []byte, err error) { + priv, err := base64.StdEncoding.DecodeString(MyPrivateEncryptionKey) + if err != nil { + log.Error().Msg("Message decryption and sign b64 failed") + } + pub, err := base64.StdEncoding.DecodeString(MyContactPublicKey) + if err != nil { + log.Error().Msg("Message decryption and sign b64 failed") + } + DecryptedMessage, err = decryptAndCheckMessage(string(pub), string(priv), crypto.NewPGPMessage(data), crypto.NewPGPSignature(Signature)) + if err != nil { + log.Error().Msg("Message decryption and sign failed") + } + return DecryptedMessage, err +} + +func encryptAndSignMessage(pub string, priv string, message *crypto.PlainMessage) (*crypto.PGPMessage, []byte, error) { + var privateKeyObj, unlockedKeyObj *crypto.Key + var privateKeyRing *crypto.KeyRing + publicKeyRing, err := createPublicKeyRing(pub) + if err != nil { + return nil, nil, err + } + + if err != nil { + return nil, nil, errors.Wrap(err, "gopenpgp: unable to encrypt message") + } + + if privateKeyObj, err = crypto.NewKeyFromArmored(priv); err != nil { + return nil, nil, errors.Wrap(err, "gopenpgp: unable to parse private key") + } + + if unlockedKeyObj, err = privateKeyObj.Unlock(nil); err != nil { + return nil, nil, errors.Wrap(err, "gopenpgp: unable to unlock key") + } + defer unlockedKeyObj.ClearPrivateParams() + + if privateKeyRing, err = crypto.NewKeyRing(unlockedKeyObj); err != nil { + return nil, nil, errors.Wrap(err, "gopenpgp: unable to create private keyring") + } + + ciphertext, err := publicKeyRing.Encrypt(message, nil) + if err != nil { + return nil, nil, errors.Wrap(err, "gopenpgp: unable to encrypt message") + } + + signature, err := privateKeyRing.SignDetached(message) + if err != nil { + return nil, nil, errors.Wrap(err, "gopenpgp: unable to encrypt message") + } + return ciphertext, signature.GetBinary(), nil +} + +func decryptAndCheckMessage(pub string, priv string, message *crypto.PGPMessage, signature *crypto.PGPSignature) ([]byte, error) { + var privateKeyObj, unlockedKeyObj *crypto.Key + var privateKeyRing *crypto.KeyRing + publicKeyRing, err := createPublicKeyRing(pub) + if err != nil { + return nil, err + } + + if err != nil { + return nil, errors.Wrap(err, "gopenpgp: unable to encrypt message") + } + + if privateKeyObj, err = crypto.NewKeyFromArmored(priv); err != nil { + return nil, errors.Wrap(err, "gopenpgp: unable to parse private key") + } + + if unlockedKeyObj, err = privateKeyObj.Unlock(nil); err != nil { + return nil, errors.Wrap(err, "gopenpgp: unable to unlock key") + } + defer unlockedKeyObj.ClearPrivateParams() + + if privateKeyRing, err = crypto.NewKeyRing(unlockedKeyObj); err != nil { + return nil, errors.Wrap(err, "gopenpgp: unable to create private keyring") + } + + plainmessage, err := privateKeyRing.Decrypt(message, nil, 0) + if err != nil { + return nil, errors.Wrap(err, "gopenpgp: unable to decrypt message") + } + + err = publicKeyRing.VerifyDetached(plainmessage, signature, crypto.GetUnixTime()) + if err != nil { + return nil, errors.Wrap(err, "gopenpgp: unable to check message signature") + } + return plainmessage.GetBinary(), nil +} diff --git a/asymcrypt_test.go b/asymcrypt_test.go index fd15ede..c0391b7 100644 --- a/asymcrypt_test.go +++ b/asymcrypt_test.go @@ -3,6 +3,7 @@ package meowlib import ( "encoding/base64" "fmt" + "io/ioutil" "log" "testing" @@ -93,6 +94,20 @@ func TestAsymEncryptDecryptSigned(t *testing.T) { assert.Equal(t, foo, string(decMess), "The two messages should be the same.") } +func TestAsymEncryptDecryptSigned2(t *testing.T) { + kp := NewKeyPair() + foo := "!#$%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_abcdefghijklmnopqrstuvwxyz{|}~" + encMess, sign, err := AsymEncryptAndSign2(kp.Public, kp.Private, []byte(foo)) + if err != nil { + log.Println(err.Error()) + } + decMess, err2 := AsymDecryptAndCheck2(kp.Private, kp.Public, encMess, sign) + if err2 != nil { + log.Println(err2.Error()) + } + assert.Equal(t, foo, string(decMess), "The two messages should be the same.") +} + func TestFlutterCompat(t *testing.T) { pub := base64.StdEncoding.EncodeToString([]byte(publicKeyECC)) priv := base64.StdEncoding.EncodeToString([]byte(privateKeyECC)) @@ -104,4 +119,63 @@ func TestFlutterCompat(t *testing.T) { println(base64.StdEncoding.EncodeToString(encMess)) println(base64.StdEncoding.EncodeToString(sign)) + +} + +func TestFlutterDecode(t *testing.T) { + pub, err := ioutil.ReadFile("/home/yves/Documents/code/flutter/meowlib/pub.key") + if err != nil { + fmt.Println("Err") + } + priv, err := ioutil.ReadFile("/home/yves/Documents/code/flutter/meowlib/priv.key") + if err != nil { + fmt.Println("Err") + } + msg, err := ioutil.ReadFile("/home/yves/Documents/code/flutter/meowlib/msg.enc") + if err != nil { + fmt.Println("Err") + } + sign, err := ioutil.ReadFile("/home/yves/Documents/code/flutter/meowlib/msg.sign") + if err != nil { + fmt.Println("Err") + } + decMsg, err := AsymDecrypt(base64.StdEncoding.EncodeToString(priv), msg) + if err != nil { + log.Println(err.Error()) + } + println(string(decMsg)) + decMsg, err = AsymDecryptAndCheck2(base64.StdEncoding.EncodeToString(priv), base64.StdEncoding.EncodeToString(pub), msg, sign) + if err != nil { + log.Println(err.Error()) + } + println(string(decMsg)) + println(base64.StdEncoding.EncodeToString(pub)) + +} + +func TestFlutterEncode(t *testing.T) { + pub, err := ioutil.ReadFile("/home/yves/Documents/code/flutter/meowlib/pub.key") + if err != nil { + fmt.Println("Err") + } + priv, err := ioutil.ReadFile("/home/yves/Documents/code/flutter/meowlib/priv.key") + if err != nil { + fmt.Println("Err") + } + + encMess, sign2, err := AsymEncryptAndSign2(base64.StdEncoding.EncodeToString(pub), base64.StdEncoding.EncodeToString(priv), []byte("Hello")) + if err != nil { + log.Println(err.Error()) + } + + err = ioutil.WriteFile("/home/yves/Documents/code/flutter/meowlib/gomsg.enc", encMess, 0644) + if err != nil { + fmt.Println("Err") + } + err = ioutil.WriteFile("/home/yves/Documents/code/flutter/meowlib/gomsg.sign", sign2, 0644) + if err != nil { + fmt.Println("Err") + } + println(base64.StdEncoding.EncodeToString(pub)) + }