abstract symmetric encryption algorithm

This commit is contained in:
rkonfj
2024-03-10 14:37:33 +08:00
parent 3b40717cbf
commit f04f14d6d2
6 changed files with 45 additions and 34 deletions

View File

@@ -171,8 +171,8 @@ type Datagram struct {
Data []byte
}
func (d *Datagram) TryDecrypt(aesCBC *secure.AESCBC) []byte {
b, err := aesCBC.Decrypt(d.Data, d.PeerID)
func (d *Datagram) TryDecrypt(symmAlgo secure.SymmAlgo) []byte {
b, err := symmAlgo.Decrypt(d.Data, d.PeerID.String())
if err != nil {
slog.Debug("Datagram decrypt error", "err", err)
return d.Data
@@ -180,8 +180,8 @@ func (d *Datagram) TryDecrypt(aesCBC *secure.AESCBC) []byte {
return b
}
func (d *Datagram) TryEncrypt(aesCBC *secure.AESCBC) []byte {
b, err := aesCBC.Encrypt(d.Data, d.PeerID)
func (d *Datagram) TryEncrypt(symmAlgo secure.SymmAlgo) []byte {
b, err := symmAlgo.Encrypt(d.Data, d.PeerID.String())
if err != nil {
slog.Debug("Datagram encrypt error", "err", err)
return d.Data

View File

@@ -6,6 +6,7 @@ import (
"github.com/rkonfj/peerguard/peer"
"github.com/rkonfj/peerguard/secure"
"github.com/rkonfj/peerguard/secure/aescbc"
)
type Config struct {
@@ -13,7 +14,7 @@ type Config struct {
PeerID peer.PeerID
DisableIPv6 bool
DisableIPv4 bool
AES *secure.AESCBC
SymmAlgo secure.SymmAlgo
Metadata peer.Metadata
OnPeer OnPeer
KeepAlivePeriod time.Duration
@@ -35,7 +36,7 @@ func ListenUDPPort(port int) Option {
func ListenPeerID(id string) Option {
return func(cfg *Config) error {
if cfg.AES != nil {
if cfg.SymmAlgo != nil {
return errors.New("options ListenPeerID and ListenPeerSecure/Curve25519 conflict")
}
peerID := peer.PeerID(id)
@@ -48,14 +49,14 @@ func ListenPeerID(id string) Option {
func ListenPeerSecure() Option {
return func(cfg *Config) error {
if cfg.AES != nil {
if cfg.SymmAlgo != nil {
return errors.New("repeat secure options")
}
priv, err := secure.GenerateCurve25519()
if err != nil {
return err
}
cfg.AES = secure.NewAESCBC(priv)
cfg.SymmAlgo = aescbc.NewAESCBC(priv.SharedKey)
cfg.PeerID = peer.PeerID(priv.PublicKey.String())
return nil
}
@@ -63,14 +64,14 @@ func ListenPeerSecure() Option {
func ListenPeerCurve25519(privateKey string) Option {
return func(cfg *Config) error {
if cfg.AES != nil {
if cfg.SymmAlgo != nil {
return errors.New("repeat secure options")
}
priv, err := secure.Curve25519PrivateKey(privateKey)
if err != nil {
return err
}
cfg.AES = secure.NewAESCBC(priv)
cfg.SymmAlgo = aescbc.NewAESCBC(priv.SharedKey)
cfg.PeerID = peer.PeerID(priv.PublicKey.String())
return nil
}

View File

@@ -54,11 +54,11 @@ func (c *PeerPacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
return
case datagram := <-c.wsConn.Datagrams():
addr = datagram.PeerID
n = copy(p, datagram.TryDecrypt(c.cfg.AES))
n = copy(p, datagram.TryDecrypt(c.cfg.SymmAlgo))
return
case datagram := <-c.udpConn.Datagrams():
addr = datagram.PeerID
n = copy(p, datagram.TryDecrypt(c.cfg.AES))
n = copy(p, datagram.TryDecrypt(c.cfg.SymmAlgo))
return
}
}
@@ -73,7 +73,7 @@ func (c *PeerPacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
}
datagram := disco.Datagram{PeerID: addr.(peer.PeerID), Data: p}
p = datagram.TryEncrypt(c.cfg.AES)
p = datagram.TryEncrypt(c.cfg.SymmAlgo)
n, err = c.udpConn.WriteToUDP(p, datagram.PeerID)
if err != nil {

View File

@@ -7,7 +7,7 @@ import (
"errors"
"time"
"github.com/rkonfj/peerguard/secure"
"github.com/rkonfj/peerguard/secure/aescbc"
)
var (
@@ -42,7 +42,7 @@ func (auth *authenticator) GenerateSecret(networkID string, validDuration time.D
if err != nil {
return "", err
}
chiperData, err := secure.AESCBCEncrypt(auth.key, b)
chiperData, err := aescbc.Encrypt(auth.key, b)
return base64.URLEncoding.EncodeToString(chiperData), err
}
@@ -51,7 +51,7 @@ func (auth *authenticator) ParseSecret(networkIDChiper string) (JSONSecret, erro
if err != nil {
return JSONSecret{}, ErrInvalidToken
}
plainData, err := secure.AESCBCDecrypt(auth.key, chiperData)
plainData, err := aescbc.Decrypt(auth.key, chiperData)
if err != nil {
return JSONSecret{}, ErrInvalidToken
}

View File

@@ -1,4 +1,4 @@
package secure
package aescbc
import (
"bytes"
@@ -11,7 +11,7 @@ import (
"sync"
"github.com/rkonfj/peerguard/lru"
"github.com/rkonfj/peerguard/peer"
"github.com/rkonfj/peerguard/secure"
)
func PKCS7Padding(data []byte, blockSize int) []byte {
@@ -35,7 +35,7 @@ func PKCS7UnPadding(data []byte) ([]byte, error) {
return data[:len(data)-int(padding)], nil
}
func AESCBCEncrypt(key, data []byte) ([]byte, error) {
func Encrypt(key, data []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
@@ -55,7 +55,7 @@ func AESCBCEncrypt(key, data []byte) ([]byte, error) {
return cipherText, nil
}
func AESCBCDecrypt(key, data []byte) ([]byte, error) {
func Decrypt(key, data []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
@@ -74,24 +74,26 @@ func AESCBCDecrypt(key, data []byte) ([]byte, error) {
return PKCS7UnPadding(data)
}
var _ secure.SymmAlgo = (*AESCBC)(nil)
type AESCBC struct {
mut sync.RWMutex
cipher *lru.Cache[peer.PeerID, cipher.Block]
priv *PrivateKey
cipher *lru.Cache[string, cipher.Block]
provideSecretKey secure.ProvideSecretKey
}
func NewAESCBC(priv *PrivateKey) *AESCBC {
func NewAESCBC(provideSecretKey secure.ProvideSecretKey) *AESCBC {
return &AESCBC{
cipher: lru.New[peer.PeerID, cipher.Block](128),
priv: priv,
cipher: lru.New[string, cipher.Block](128),
provideSecretKey: provideSecretKey,
}
}
func (s *AESCBC) Encrypt(b []byte, peerID peer.PeerID) ([]byte, error) {
func (s *AESCBC) Encrypt(b []byte, pubKey string) ([]byte, error) {
if s == nil {
return nil, errors.New("aesCBC is nil")
}
block, err := s.ensureChiperBlock(peerID)
block, err := s.ensureChiperBlock(pubKey)
if err != nil {
return nil, err
}
@@ -108,11 +110,11 @@ func (s *AESCBC) Encrypt(b []byte, peerID peer.PeerID) ([]byte, error) {
return cipherText, nil
}
func (s *AESCBC) Decrypt(b []byte, peerID peer.PeerID) ([]byte, error) {
func (s *AESCBC) Decrypt(b []byte, pubKey string) ([]byte, error) {
if s == nil {
return nil, errors.New("aesCBC is nil")
}
block, err := s.ensureChiperBlock(peerID)
block, err := s.ensureChiperBlock(pubKey)
if err != nil {
return nil, err
}
@@ -129,12 +131,12 @@ func (s *AESCBC) Decrypt(b []byte, peerID peer.PeerID) ([]byte, error) {
return PKCS7UnPadding(plainBytes)
}
func (s *AESCBC) ensureChiperBlock(peerID peer.PeerID) (cipher.Block, error) {
func (s *AESCBC) ensureChiperBlock(pubKey string) (cipher.Block, error) {
s.mut.RLock()
block, ok := s.cipher.Get(peerID)
block, ok := s.cipher.Get(pubKey)
s.mut.RUnlock()
if !ok {
secretKey, err := s.priv.SharedKey(peerID.String())
secretKey, err := s.provideSecretKey(pubKey)
if err != nil {
return nil, err
}
@@ -144,7 +146,7 @@ func (s *AESCBC) ensureChiperBlock(peerID peer.PeerID) (cipher.Block, error) {
}
block = b
s.mut.Lock()
s.cipher.Put(peerID, block)
s.cipher.Put(pubKey, block)
s.mut.Unlock()
}

8
secure/symm_algo.go Normal file
View File

@@ -0,0 +1,8 @@
package secure
type ProvideSecretKey func(pubKey string) ([]byte, error)
type SymmAlgo interface {
Encrypt(data []byte, pubKey string) ([]byte, error)
Decrypt(data []byte, pubKey string) ([]byte, error)
}