mirror of
https://github.com/sigcn/pg.git
synced 2025-10-25 00:00:34 +08:00
abstract symmetric encryption algorithm
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
8
secure/symm_algo.go
Normal 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)
|
||||
}
|
||||
Reference in New Issue
Block a user