AsymCrypt optimize + Symcrypt creation

This commit is contained in:
ycc 2022-09-18 21:17:28 +02:00
parent 01aec23f76
commit 35fa29f5b9
9 changed files with 199 additions and 22 deletions

View File

@ -6,6 +6,7 @@ import (
"github.com/ProtonMail/gopenpgp/v2/crypto"
"github.com/ProtonMail/gopenpgp/v2/helper"
"github.com/pkg/errors"
"github.com/rs/zerolog/log"
)
@ -49,7 +50,33 @@ func (Kp *KeyPair) GetCryptoKeyObject() *crypto.Key {
return key
}
func Encrypt(PublicKey string, data []byte) ([]byte, error) {
func AsymEncrypt(publicKey string, data []byte) ([]byte, error) {
pub, err := base64.StdEncoding.DecodeString(publicKey)
if err != nil {
log.Error().Msg("Message encryption b64 failed")
}
ciphertext, err := encryptMessage(string(pub), crypto.NewPlainMessage(data))
if err != nil {
log.Error().Msg("Message encryption failed")
return nil, err
}
return ciphertext.GetBinary(), err
}
func AsymDecrypt(PrivateKey string, data []byte) ([]byte, error) {
priv, err := base64.StdEncoding.DecodeString(PrivateKey)
if err != nil {
log.Error().Msg("Message decryption b64 failed")
}
decrypted, err := decryptMessage(string(priv), nil, crypto.NewPGPMessage(data))
if err != nil {
log.Error().Msg("Message decryption failed")
}
return decrypted.GetBinary(), err
}
func AsymEncryptArmored(PublicKey string, data []byte) ([]byte, error) {
pub, err := base64.StdEncoding.DecodeString(PublicKey)
if err != nil {
log.Error().Msg("Message encryption b64 failed")
@ -61,7 +88,7 @@ func Encrypt(PublicKey string, data []byte) ([]byte, error) {
return []byte(armor), err
}
func Decrypt(PrivateKey string, data []byte) ([]byte, error) {
func AsymDecryptArmored(PrivateKey string, data []byte) ([]byte, error) {
priv, err := base64.StdEncoding.DecodeString(PrivateKey)
if err != nil {
log.Error().Msg("Message decryption b64 failed")
@ -73,7 +100,7 @@ func Decrypt(PrivateKey string, data []byte) ([]byte, error) {
return []byte(decrypted), err
}
func EncryptAndSign(PublicEncryptionKey string, PrivateSignatureKey string, data []byte) ([]byte, []byte, error) {
func AsymEncryptAndSign(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")
@ -89,7 +116,7 @@ func EncryptAndSign(PublicEncryptionKey string, PrivateSignatureKey string, data
return []byte(encrypted), []byte(signature), err
}
func DecryptAndCheck(MyPrivateEncryptionKey string, MyContactPublicKey string, data []byte, Signature []byte) (DecryptedMessage []byte, err error) {
func AsymDecryptAndCheck(MyPrivateEncryptionKey string, MyContactPublicKey string, data []byte, Signature []byte) (DecryptedMessage []byte, err error) {
pub, err := base64.StdEncoding.DecodeString(MyPrivateEncryptionKey)
if err != nil {
log.Error().Msg("Message decryption and sign b64 failed")
@ -104,3 +131,64 @@ func DecryptAndCheck(MyPrivateEncryptionKey string, MyContactPublicKey string, d
}
return DecryptedMessage, err
}
func encryptMessage(key string, message *crypto.PlainMessage) (*crypto.PGPMessage, error) {
publicKeyRing, err := createPublicKeyRing(key)
if err != nil {
return nil, err
}
ciphertext, err := publicKeyRing.Encrypt(message, nil)
if err != nil {
return nil, errors.Wrap(err, "gopenpgp: unable to encrypt message")
}
return ciphertext, nil
}
func decryptMessage(privateKey string, passphrase []byte, ciphertext *crypto.PGPMessage) (*crypto.PlainMessage, error) {
privateKeyObj, err := crypto.NewKeyFromArmored(privateKey)
if err != nil {
return nil, errors.Wrap(err, "gopenpgp: unable to parse the private key")
}
privateKeyUnlocked, err := privateKeyObj.Unlock(passphrase)
if err != nil {
return nil, errors.Wrap(err, "gopenpgp: unable to unlock key")
}
defer privateKeyUnlocked.ClearPrivateParams()
privateKeyRing, err := crypto.NewKeyRing(privateKeyUnlocked)
if err != nil {
return nil, errors.Wrap(err, "gopenpgp: unable to create the private key ring")
}
message, err := privateKeyRing.Decrypt(ciphertext, nil, 0)
if err != nil {
return nil, errors.Wrap(err, "gopenpgp: unable to decrypt message")
}
return message, nil
}
func createPublicKeyRing(publicKey string) (*crypto.KeyRing, error) {
publicKeyObj, err := crypto.NewKeyFromArmored(publicKey)
if err != nil {
return nil, errors.Wrap(err, "gopenpgp: unable to parse public key")
}
if publicKeyObj.IsPrivate() {
publicKeyObj, err = publicKeyObj.ToPublic()
if err != nil {
return nil, errors.Wrap(err, "gopenpgp: unable to extract public key from private key")
}
}
publicKeyRing, err := crypto.NewKeyRing(publicKeyObj)
if err != nil {
return nil, errors.Wrap(err, "gopenpgp: unable to create new keyring")
}
return publicKeyRing, nil
}

View File

@ -29,28 +29,29 @@ func TestGetKey(t *testing.T) {
//}
}
func TestEncryptDecrypt(t *testing.T) {
func TestAsymEncryptDecrypt(t *testing.T) {
kp := NewKeyPair()
foo := "totoaimelesfrites!"
encMess, err := Encrypt(kp.Public, []byte(foo))
foo := []byte("!#$%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_abcdefghijklmnopqrstuvwxyz{|}~")
encMess, err := AsymEncrypt(kp.Public, foo)
if err != nil {
log.Println(err.Error())
}
decMess, err2 := Decrypt(kp.Private, encMess)
println("len enc:", len(encMess))
decMess, err2 := AsymDecrypt(kp.Private, encMess)
if err2 != nil {
log.Println(err2.Error())
}
assert.Equal(t, foo, decMess, "The two messages should be the same.")
}
func TestEncryptDecryptSigned(t *testing.T) {
func TestAsymEncryptDecryptSigned(t *testing.T) {
kp := NewKeyPair()
foo := "totoaimelesfrites!"
encMess, sign, err := EncryptAndSign(kp.Public, kp.Private, []byte(foo))
foo := "!#$%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_abcdefghijklmnopqrstuvwxyz{|}~"
encMess, sign, err := AsymEncryptAndSign(kp.Public, kp.Private, []byte(foo))
if err != nil {
log.Println(err.Error())
}
decMess, err2 := DecryptAndCheck(kp.Private, kp.Public, encMess, sign)
decMess, err2 := AsymDecryptAndCheck(kp.Private, kp.Public, encMess, sign)
if err2 != nil {
log.Println(err2.Error())
}

View File

@ -55,18 +55,17 @@ func (pl *PeerList) GetFromName(name string) *Peer {
// AsymEncryptMessage prepares a message to send to a specific peer contact
func (p *Peer) AsymEncryptMessage(Message []byte) (EncryptedMessage []byte, Signature []byte, Servers []*meowlib.Server, err error) {
EncryptedMessage, Signature, err = meowlib.EncryptAndSign(p.Contact.EncryptionPublicKey, p.Me.Private, Message)
EncryptedMessage, Signature, err = meowlib.AsymEncryptAndSign(p.Contact.EncryptionPublicKey, p.Me.Private, Message)
if err != nil {
fmt.Println(err.Error())
return nil, nil, nil, err
}
return EncryptedMessage, Signature, p.Contact.PullServers, err
}
// AsymDecryptMessage reads a message from a specific peer contact
func (p *Peer) AsymDecryptMessage(Message []byte, Signature []byte) (DecryptedMessage []byte, err error) {
DecryptedMessage, err = meowlib.DecryptAndCheck(p.Me.Private, p.Contact.ContactPublicKey, Message, Signature)
DecryptedMessage, err = meowlib.AsymDecryptAndCheck(p.Me.Private, p.Contact.ContactPublicKey, Message, Signature)
if err != nil {
fmt.Println(err.Error())
return nil, err
@ -101,6 +100,6 @@ func (p *Peer) LoadLastMessages(qty int) {
}
func (p *Peer) GetLastMessageUid(msg []byte) {
func (p *Peer) GetLastMessageUuid(msg []byte) {
}

View File

@ -37,7 +37,7 @@ func (sl *InternalServerList) AddUrls(urls []string) {
// AsymEncryptMessage prepares a message to send to a specific internal server
func (ints *InternalServer) AsymEncryptMessage(Message []byte) (EncryptedMessage []byte, Signature []byte, err error) {
EncryptedMessage, Signature, err = meowlib.EncryptAndSign(ints.ServerData.PublicKey, ints.Me.Private, Message)
EncryptedMessage, Signature, err = meowlib.AsymEncryptAndSign(ints.ServerData.PublicKey, ints.Me.Private, Message)
if err != nil {
fmt.Println(err.Error())
return nil, nil, err
@ -47,7 +47,7 @@ func (ints *InternalServer) AsymEncryptMessage(Message []byte) (EncryptedMessage
// AsymDecryptMessage reads a message from a specific internal server
func (ints *InternalServer) AsymDecryptMessage(Message []byte, Signature []byte) (DecryptedMessage []byte, err error) {
DecryptedMessage, err = meowlib.DecryptAndCheck(ints.Me.Private, ints.ServerData.PublicKey, Message, Signature)
DecryptedMessage, err = meowlib.AsymDecryptAndCheck(ints.Me.Private, ints.ServerData.PublicKey, Message, Signature)
if err != nil {
fmt.Println(err.Error())
return nil, err

1
go.mod
View File

@ -5,6 +5,7 @@ go 1.16
require (
github.com/ProtonMail/gopenpgp/v2 v2.2.4
github.com/makiuchi-d/gozxing v0.1.1
github.com/pkg/errors v0.9.1
github.com/rs/zerolog v1.25.0
github.com/stretchr/testify v1.4.0
google.golang.org/protobuf v1.28.1

View File

@ -53,7 +53,7 @@ func (id *Identity) Save(file string) error {
// AsymEncryptMessage prepares a message to send to a specific client contact
func (id *Identity) AsymEncryptMessage(ClientPublicKey string, Message []byte) (EncryptedMsg []byte, Signature []byte, err error) {
EncryptedMsg, Signature, err = meowlib.EncryptAndSign(ClientPublicKey, id.ServerKp.Private, Message)
EncryptedMsg, Signature, err = meowlib.AsymEncryptAndSign(ClientPublicKey, id.ServerKp.Private, Message)
if err != nil {
fmt.Println(err.Error())
return nil, nil, err
@ -63,7 +63,7 @@ func (id *Identity) AsymEncryptMessage(ClientPublicKey string, Message []byte) (
// AsymDecryptMessage reads a message from a specific client contact
func (id *Identity) AsymDecryptMessage(ClientPublicKey string, Message []byte, Signature []byte) (DecryptedMsg []byte, err error) {
DecryptedMsg, err = meowlib.DecryptAndCheck(id.ServerKp.Private, ClientPublicKey, Message, Signature)
DecryptedMsg, err = meowlib.AsymDecryptAndCheck(id.ServerKp.Private, ClientPublicKey, Message, Signature)
if err != nil {
fmt.Println(err.Error())
return nil, err

View File

@ -36,7 +36,7 @@ func (sl *InternalServerList) AddUrls(urls []string) {
// AsymEncryptMessage prepares a message to send to a specific internal server
func (ints *InternalServer) AsymEncryptMessage(Message []byte) (EncryptedMsg []byte, Signature []byte, err error) {
EncryptedMsg, Signature, err = meowlib.EncryptAndSign(ints.ServerData.PublicKey, ints.Me.Private, Message)
EncryptedMsg, Signature, err = meowlib.AsymEncryptAndSign(ints.ServerData.PublicKey, ints.Me.Private, Message)
if err != nil {
fmt.Println(err.Error())
return nil, nil, err
@ -46,7 +46,7 @@ func (ints *InternalServer) AsymEncryptMessage(Message []byte) (EncryptedMsg []b
// AsymDecryptMessage reads a message from a specific internal server
func (ints *InternalServer) AsymDecryptMessage(Message []byte, Signature []byte) (DecryptedMsg []byte, err error) {
DecryptedMsg, err = meowlib.DecryptAndCheck(ints.Me.Private, ints.ServerData.PublicKey, Message, Signature)
DecryptedMsg, err = meowlib.AsymDecryptAndCheck(ints.Me.Private, ints.ServerData.PublicKey, Message, Signature)
if err != nil {
fmt.Println(err.Error())
return nil, err

67
symcrypt.go Normal file
View File

@ -0,0 +1,67 @@
package meowlib
import (
"encoding/base64"
"github.com/ProtonMail/gopenpgp/v2/crypto"
"github.com/ProtonMail/gopenpgp/v2/helper"
"github.com/pkg/errors"
"github.com/rs/zerolog/log"
)
func SymEncrypt(password string, data []byte) ([]byte, error) {
var pgpMessage *crypto.PGPMessage
var err error
var message = crypto.NewPlainMessage(data)
pgpMessage, err = crypto.EncryptMessageWithPassword(message, []byte(password))
if err != nil {
return nil, errors.Wrap(err, "gopenpgp: unable to encrypt message with password")
}
return pgpMessage.GetBinary(), nil
}
func SymDecrypt(password string, data []byte) ([]byte, error) {
var message *crypto.PlainMessage
var pgpMessage *crypto.PGPMessage
var err error
pgpMessage = crypto.NewPGPMessage(data)
message, err = crypto.DecryptMessageWithPassword(pgpMessage, []byte(password))
if err != nil {
return nil, errors.Wrap(err, "gopenpgp: unable to decrypt message with password")
}
return message.GetBinary(), nil
}
func SymEncryptAndSign(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")
}
encrypted, signature, err := helper.EncryptSignBinaryDetached(string(pub), string(priv), nil, data)
if err != nil {
log.Error().Msg("Message encryption and sign failed")
}
return []byte(encrypted), []byte(signature), err
}
func SymDecryptAndCheck(MyPrivateEncryptionKey string, MyContactPublicKey string, data []byte, Signature []byte) (DecryptedMessage []byte, err error) {
pub, err := base64.StdEncoding.DecodeString(MyPrivateEncryptionKey)
if err != nil {
log.Error().Msg("Message decryption and sign b64 failed")
}
priv, err := base64.StdEncoding.DecodeString(MyContactPublicKey)
if err != nil {
log.Error().Msg("Message decryption and sign b64 failed")
}
DecryptedMessage, err = helper.DecryptVerifyBinaryDetached(string(pub), string(priv), nil, data, string(Signature))
if err != nil {
log.Error().Msg("Message decryption and sign failed")
}
return DecryptedMessage, err
}

21
symcrypt_test.go Normal file
View File

@ -0,0 +1,21 @@
package meowlib
import (
"log"
"testing"
"github.com/stretchr/testify/assert"
)
func TestSymEncryptDecrypt(t *testing.T) {
foo := []byte("!#$%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_abcdefghijklmnopqrstuvwxyz{|}~")
encMess, err := SymEncrypt("mysecretpassword", foo)
if err != nil {
log.Println(err.Error())
}
decMess, err2 := SymDecrypt("mysecretpassword", encMess)
if err2 != nil {
log.Println(err2.Error())
}
assert.Equal(t, foo, decMess, "The two messages should be the same.")
}