Skip to content

Commit

Permalink
Changed the previous encryption with AES/GCM. Altough is not perfect,…
Browse files Browse the repository at this point in the history
… the implementation from Google is

pretty good. Besides, to use the same string for IV and for Key, using CBC, was not a good idea: the IV is
usually attached to the encrypted payload. So you attach the key to each packet.
Please notice, the tests (crypt_test.go) will fail because the signature of function has changed.(EncryptIV , DecryptIV)
Unfortunately I wasn't able to understand this piece of code and what it was aiming to, so I didn't changed.
  • Loading branch information
LowEel committed Jul 2, 2017
1 parent 4474ad3 commit f4e50d5
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 40 deletions.
25 changes: 13 additions & 12 deletions common/net_table.go
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
package common

import (
"github.com/meshbird/meshbird/log"
"github.com/meshbird/meshbird/network/protocol"
"github.com/meshbird/meshbird/secure"
"net"
"sync"
"time"

"github.com/meshbird/meshbird/log"
"github.com/meshbird/meshbird/network/protocol"
"github.com/meshbird/meshbird/secure"
)

type NetTable struct {
BaseService

localNode *LocalNode
waitGroup sync.WaitGroup
dhtInChan chan string
localNode *LocalNode
waitGroup sync.WaitGroup
dhtInChan chan string

lock sync.RWMutex
blackList map[string]time.Time
peers map[string]*RemoteNode
lock sync.RWMutex
blackList map[string]time.Time
peers map[string]*RemoteNode

heartbeatTicker <-chan time.Time

logger log.Logger
logger log.Logger
}

func (nt NetTable) Name() string {
Expand Down Expand Up @@ -55,7 +56,7 @@ func (nt *NetTable) Stop() {
}
}

func (nt *NetTable) GetDHTInChannel() chan <- string {
func (nt *NetTable) GetDHTInChannel() chan<- string {
return nt.dhtInChan
}

Expand Down Expand Up @@ -164,7 +165,7 @@ func (nt *NetTable) SendPacket(dstIP net.IP, payload []byte) {
return
}

payloadEnc, err := secure.EncryptIV(payload, nt.localNode.State().Secret.Key, nt.localNode.State().Secret.Key)
payloadEnc, err := secure.EncryptIV(payload, nt.localNode.State().Secret.Key)
if err != nil {
nt.logger.Error("error on encrypt, %v", err)
return
Expand Down
5 changes: 3 additions & 2 deletions common/remotenode.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"io"
"net"
"time"

"github.com/meshbird/meshbird/log"
"github.com/meshbird/meshbird/network/protocol"
"github.com/meshbird/meshbird/secure"
Expand Down Expand Up @@ -80,7 +81,7 @@ func (rn *RemoteNode) listen(ln *LocalNode) {
case protocol.TypeTransfer:
rn.logger.Debug("Writing to interface...")
payloadEncrypted := pack.Data.Msg.(protocol.TransferMessage).Bytes()
payload, errDec := secure.DecryptIV(payloadEncrypted, ln.State().Secret.Key, ln.State().Secret.Key)
payload, errDec := secure.DecryptIV(payloadEncrypted, ln.State().Secret.Key)
if errDec != nil {
rn.logger.Error("error on decrypt, %v", err)
break
Expand All @@ -96,4 +97,4 @@ func (rn *RemoteNode) listen(ln *LocalNode) {
rn.lastHeartbeat = time.Now()
}
}
}
}
66 changes: 41 additions & 25 deletions secure/crypt.go
Original file line number Diff line number Diff line change
@@ -1,43 +1,59 @@
package secure

import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"io"
"log"
)

func EncryptIV(decrypted []byte, key []byte, iv []byte) ([]byte, error) {
ac, err := aes.NewCipher(key)
func EncryptIV(decrypted []byte, key []byte) ([]byte, error) {

c, err := aes.NewCipher(key)
if err != nil {
log.Println("[CRYPT][AES][ENC] Problem %s", err.Error())
return nil, err
}
c := cipher.NewCBCEncrypter(ac, iv)
decrypted = PKCS5Padding(decrypted, ac.BlockSize())
encrypted := make([]byte, len(decrypted))
c.CryptBlocks(encrypted, decrypted)
return encrypted, nil
}

func DecryptIV(encrypted []byte, key []byte, iv []byte) ([]byte, error) {
ac, err := aes.NewCipher(key)
gcm, err := cipher.NewGCM(c)
if err != nil {
log.Println("[CRYPT][AES][ENC] Problem %s", err.Error())
return nil, err
}

nonce := make([]byte, gcm.NonceSize())
if _, err = io.ReadFull(rand.Reader, nonce); err != nil {
log.Println("[CRYPT][AES][NONCE] Problem %s", err.Error())
return nil, err
}
c := cipher.NewCBCDecrypter(ac, iv)
decrypted := make([]byte, len(encrypted))
c.CryptBlocks(decrypted, encrypted)
decrypted = PKCS5UnPadding(decrypted)
return decrypted, nil
}

func PKCS5Padding(src []byte, blockSize int) []byte {
padding := blockSize - len(src)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(src, padtext...)
return gcm.Seal(nonce, nonce, decrypted, nil), nil

}

func PKCS5UnPadding(src []byte) []byte {
length := len(src)
unpadding := int(src[length-1])
return src[:(length - unpadding)]
func DecryptIV(ciphertext []byte, key []byte) ([]byte, error) {

c, err := aes.NewCipher(key)
if err != nil {
log.Println("[DECRYPT][AES] Problem %s", err.Error())
return nil, err
}

gcm, err := cipher.NewGCM(c)
if err != nil {
log.Println("[DECRYPT][AES] Problem %s", err.Error())
return nil, err
}

nonceSize := gcm.NonceSize()
if len(ciphertext) < nonceSize {
log.Println("[DECRYPT][AES] Problem %s", "Cyphertext too short")
return nil, err
}

nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:]

return gcm.Open(nil, nonce, ciphertext, nil)

}
2 changes: 1 addition & 1 deletion secure/crypt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func BenchmarkEncryptAesCbc(b *testing.B) {
func BenchmarkDescryptAesCbc(b *testing.B) {
key := randomBytes(16)
iv := randomBytes(16)
encrypted, err := EncryptIV(original, key, iv)
encrypted, err := EncryptIV(original, key)
if err != nil {
b.Fatal(err)
}
Expand Down

0 comments on commit f4e50d5

Please sign in to comment.