faster encryption by generating key once

This commit is contained in:
Zack Scholl 2019-04-27 11:15:38 -07:00
parent 14dd892377
commit 249c0d8ab0
3 changed files with 53 additions and 95 deletions

View File

@ -5,85 +5,50 @@ import (
"crypto/cipher"
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"errors"
"strings"
"golang.org/x/crypto/pbkdf2"
)
// Encryption stores the data
type Encryption struct {
Encrypted []byte `json:"e"`
Salt []byte `json:"s"`
IV []byte `json:"i"`
key []byte
passphrase []byte
Salt []byte `json:"s"`
}
func (e Encryption) Bytes() []byte {
return []byte(base64.StdEncoding.EncodeToString(e.Encrypted) + "-" + base64.StdEncoding.EncodeToString(e.Salt) + "-" + base64.StdEncoding.EncodeToString(e.IV))
}
func FromBytes(b []byte) (enc Encryption, err error) {
enc = Encryption{}
items := strings.Split(string(b), "-")
if len(items) != 3 {
err = errors.New("not valid")
return
// New generates a new encryption, using the supplied passphrase and
// an optional supplied salt.
func New(passphrase []byte, salt []byte) (e Encryption, err error) {
e.passphrase = passphrase
if salt == nil {
e.Salt = make([]byte, 8)
// http://www.ietf.org/rfc/rfc2898.txt
// Salt.
rand.Read(e.Salt)
} else {
e.Salt = salt
}
enc.Encrypted, err = base64.StdEncoding.DecodeString(items[0])
if err != nil {
return
}
enc.Salt, err = base64.StdEncoding.DecodeString(items[1])
if err != nil {
return
}
enc.IV, err = base64.StdEncoding.DecodeString(items[2])
e.key = pbkdf2.Key([]byte(passphrase), e.Salt, 100, 32, sha256.New)
return
}
// Encrypt will generate an encryption
func Encrypt(plaintext []byte, passphrase []byte, dontencrypt ...bool) Encryption {
if len(dontencrypt) > 0 && dontencrypt[0] {
return Encryption{
Encrypted: plaintext,
Salt: []byte("salt"),
IV: []byte("iv"),
}
}
key, saltBytes := deriveKey(passphrase, nil)
ivBytes := make([]byte, 12)
// Encrypt will generate an encryption, prefixed with the IV
func (e Encryption) Encrypt(plaintext []byte) []byte {
// generate a random iv each time
// http://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf
// Section 8.2
ivBytes := make([]byte, 12)
rand.Read(ivBytes)
b, _ := aes.NewCipher(key)
b, _ := aes.NewCipher(e.key)
aesgcm, _ := cipher.NewGCM(b)
encrypted := aesgcm.Seal(nil, ivBytes, plaintext, nil)
return Encryption{
Encrypted: encrypted,
Salt: saltBytes,
IV: ivBytes,
}
return append(ivBytes, encrypted...)
}
// Decrypt an encryption
func (e Encryption) Decrypt(passphrase []byte, dontencrypt ...bool) (plaintext []byte, err error) {
if len(dontencrypt) > 0 && dontencrypt[0] {
return e.Encrypted, nil
}
key, _ := deriveKey(passphrase, e.Salt)
b, _ := aes.NewCipher(key)
func (e Encryption) Decrypt(encrypted []byte) (plaintext []byte, err error) {
b, _ := aes.NewCipher(e.key)
aesgcm, _ := cipher.NewGCM(b)
plaintext, err = aesgcm.Open(nil, e.IV, e.Encrypted, nil)
plaintext, err = aesgcm.Open(nil, encrypted[:12], encrypted[12:], nil)
return
}
func deriveKey(passphrase []byte, salt []byte) ([]byte, []byte) {
if salt == nil {
salt = make([]byte, 8)
// http://www.ietf.org/rfc/rfc2898.txt
// Salt.
rand.Read(salt)
}
return pbkdf2.Key([]byte(passphrase), salt, 100, 32, sha256.New), salt
}

View File

@ -1,41 +1,32 @@
package crypt
import "testing"
import (
"testing"
func BenchmarkEncryption(b *testing.B) {
"github.com/stretchr/testify/assert"
)
func BenchmarkEncryptionNew(b *testing.B) {
for i := 0; i < b.N; i++ {
Encrypt([]byte(`
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse laoreet justo quis augue vehicula ornare. Nullam nec risus volutpat nulla dictum consectetur. Phasellus porttitor, justo non tincidunt finibus, massa justo iaculis urna, eget mattis nulla libero vitae risus. Vestibulum vehicula nunc id dignissim rutrum. Cras varius ac nulla a imperdiet. Sed finibus, libero in tempor hendrerit, turpis erat faucibus nisl, a consectetur massa mi eget mi. Vestibulum pulvinar lorem id ipsum elementum auctor.
Morbi at odio a eros eleifend faucibus. Sed at tempor urna, in interdum neque. Curabitur condimentum rhoncus orci, vel vulputate risus ultricies efficitur. Curabitur eu vehicula ligula. Curabitur suscipit ex vitae nunc faucibus vehicula. Mauris sed dictum mauris. Vivamus nec dui at urna porttitor suscipit. Integer ut eros finibus orci consectetur hendrerit id quis dolor. Proin dapibus orci quis massa viverra finibus. Sed quis ligula neque.
Aenean et fringilla nulla. In et venenatis massa, vel feugiat diam. Sed ornare felis nec egestas suscipit. Sed a ultricies sapien. Aliquam ex leo, tincidunt faucibus neque non, vehicula commodo velit. Vestibulum molestie efficitur velit in vestibulum. Aliquam eget leo felis. Etiam pharetra vulputate egestas. Cras gravida nibh eu sollicitudin facilisis. Nulla facilisi. Nulla tristique arcu vitae arcu pulvinar feugiat. Suspendisse finibus a urna a cursus. Donec bibendum sodales nunc eget tincidunt. Pellentesque blandit ac nunc at consectetur.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce congue nibh nisl, et porttitor mauris tempor eget. Vivamus sit amet sagittis ligula. Quisque aliquam orci non odio egestas, vel semper felis efficitur. Vivamus non leo lacus. Etiam non ligula eget erat porta laoreet id id ligula. Proin imperdiet erat id efficitur vehicula. Suspendisse potenti. Morbi ornare finibus metus, eu pretium leo tristique sit amet. Praesent placerat elit quis porttitor rhoncus. Vestibulum consectetur turpis sed lacus placerat, vel laoreet est interdum. Proin id quam ut risus tempor hendrerit nec eu lacus. Duis vel aliquam ex.
Sed facilisis in ex vitae pellentesque. Donec tempor lobortis dui. Praesent sagittis, elit ac dictum hendrerit, eros risus auctor erat, in pretium nulla mi et felis. Nullam imperdiet erat id erat rutrum fermentum. Praesent ultrices, diam non efficitur gravida, sem quam fermentum est, vitae tristique libero velit eget turpis. Nunc sem risus, venenatis nec suscipit quis, accumsan eu nunc. Fusce fringilla sit amet purus vel ornare. Donec nulla dolor, gravida ac metus nec, tincidunt feugiat sem. Fusce semper varius nunc.
Nulla facilisi. Quisque in euismod ex, ac sollicitudin dolor. Aliquam erat volutpat. Etiam nisl sem, posuere et pellentesque fermentum, pretium non lorem. Nunc blandit nisl at leo interdum gravida. Proin ullamcorper ultrices dictum. Pellentesque non ligula magna. Sed justo nibh, finibus vitae malesuada ultricies, molestie ac ante. Suspendisse maximus congue viverra.
Donec a est eu arcu tristique fermentum a quis velit. Aenean eu mollis turpis. Morbi euismod risus eros, at vestibulum lectus iaculis sed. Pellentesque varius eu justo in viverra. Phasellus feugiat tincidunt urna ut accumsan. In ullamcorper vehicula hendrerit. Sed sapien diam, rhoncus nec porta non, gravida et ante. Nulla et volutpat quam, nec venenatis ex. Donec vitae dictum libero, id ornare sapien. Morbi id aliquam ipsum. Cras a ultricies purus.
Morbi sit amet sagittis metus, vitae dictum nunc. Pellentesque ornare consequat diam, vitae maximus dolor facilisis at. Cras semper imperdiet mollis. Fusce maximus augue quis elit pulvinar, vitae varius nunc tempus. Maecenas et suscipit leo. Morbi tempus neque enim, sit amet vestibulum ex sollicitudin ac. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vel rutrum nisl. Nullam ac vehicula velit. Sed suscipit lacus libero, ac laoreet tortor vehicula a. In aliquam tellus tincidunt ligula fringilla, ut finibus lorem commodo. Sed sit amet porta magna, et aliquam lacus.
Nulla at libero in velit lacinia feugiat sed sit amet erat. Cras nec iaculis magna. Curabitur efficitur turpis vel risus euismod, sit amet posuere orci efficitur. Nunc tincidunt ante eu nunc lacinia, varius dignissim tellus eleifend. Pellentesque enim urna, porttitor eget tincidunt ut, sollicitudin in enim. Donec sit amet hendrerit orci, ut viverra arcu. Nam vitae semper est. Vestibulum aliquet dolor sed turpis blandit eleifend. Nullam auctor accumsan mauris eu mattis. Etiam interdum purus sit amet libero placerat vehicula.
Ut ac odio risus. Sed ut dolor ut metus tincidunt egestas. Curabitur ullamcorper lectus interdum nisi euismod, et faucibus dui fringilla. Nunc at purus vel erat hendrerit dapibus a ut ligula. Nulla facilisi. Etiam gravida, dui nec posuere gravida, nunc quam sodales dui, ut congue mauris tortor vitae nunc. Praesent dapibus mi quis pulvinar consequat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque ultricies placerat dolor tempus cursus. Etiam vehicula, dui vel varius ullamcorper, sapien sem malesuada felis, quis suscipit est nibh vel massa.
Nulla sed mollis enim. Interdum et malesuada fames ac ante ipsum primis in faucibus. Quisque magna purus, faucibus vel ornare vel, semper et odio. Donec non interdum nunc. Maecenas metus augue, maximus ac volutpat id, euismod eget sem. Sed efficitur non diam sed ultrices. Fusce ultrices nisl et suscipit tristique. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi luctus augue vel vehicula iaculis.
Vivamus iaculis luctus nisl, quis molestie purus mollis vitae. Proin vehicula rutrum finibus. Nulla lacinia auctor tincidunt. Vivamus sollicitudin orci eu porttitor vehicula. Vivamus auctor sem sed risus porta cursus. Donec orci dui, lacinia vitae mi quis, tincidunt feugiat elit. Mauris pharetra faucibus justo non volutpat. Praesent pellentesque condimentum quam quis porta. Praesent sed nisi id eros iaculis condimentum nec in libero. Donec eu blandit enim. Aliquam nec elementum libero. Donec nec nisi suscipit felis blandit rutrum. Morbi magna nulla, porttitor id nisl vitae, imperdiet efficitur leo. Ut eu vestibulum justo, vitae dapibus felis.
Quisque ac est nec metus sagittis lobortis mollis id metus. Duis a augue eu erat vulputate facilisis varius ac nunc. Suspendisse eleifend enim suscipit erat aliquet, sed feugiat ligula tempor. Aenean dapibus felis porttitor mauris ultricies vehicula. Vestibulum lacinia scelerisque turpis, ut varius nunc suscipit vitae. Praesent blandit mauris eu semper lacinia. Cras mauris augue, tincidunt quis risus tincidunt, blandit euismod erat. Etiam non sagittis leo, eget pharetra risus.
Donec sodales ultricies neque, non accumsan velit blandit non. Aliquam lacinia orci mauris, commodo porttitor ipsum venenatis sed. Integer sit amet pretium nisi. Ut porttitor, sapien quis gravida egestas, nulla tellus ullamcorper ante, et eleifend diam turpis et odio. Quisque dui orci, commodo sit amet rhoncus ut, pharetra ac leo. Suspendisse non vehicula ex. Morbi gravida lacus vitae ex lacinia, nec aliquam purus consequat. Donec aliquam pretium massa, id viverra nunc blandit sit amet. Donec sed dapibus elit. Cras hendrerit efficitur eros quis malesuada. Aenean a massa in dolor gravida volutpat a et nisi. Nullam sit amet est tempus, condimentum odio egestas, dignissim nibh. Integer tempor id sapien at sagittis.
Aliquam in urna semper, suscipit metus in, pharetra lectus. Proin tempor nibh turpis, a pulvinar justo mollis sit amet. Fusce massa turpis, tristique id semper sit amet, venenatis in mauris. Maecenas id consectetur purus, sed efficitur ipsum. Sed pretium nisi ut sem pulvinar ullamcorper. Nullam at nunc et quam rhoncus egestas eu eu odio. Nullam commodo urna cursus massa porta consectetur. Sed blandit erat ut imperdiet malesuada. Cras nec fringilla ante. Nam sed gravida urna. Nam non dui quis turpis efficitur feugiat. Fusce in quam ex.
Nullam purus libero, egestas eget luctus et, malesuada eget est. Curabitur tristique sollicitudin est, imperdiet cras amet. `), []byte(`password`))
bob, _ := New([]byte("password"), nil)
bob.Encrypt([]byte("hello, world"))
}
}
func BenchmarkEncryption(b *testing.B) {
bob, _ := New([]byte("password"), nil)
for i := 0; i < b.N; i++ {
bob.Encrypt([]byte("hello, world"))
}
}
func TestEncryption(t *testing.T) {
bob, err := New([]byte("password"), nil)
assert.Nil(t, err)
jane, err := New([]byte("password"), bob.Salt)
assert.Nil(t, err)
enc := bob.Encrypt([]byte("hello, world"))
dec, err := jane.Decrypt(enc)
assert.Nil(t, err)
assert.Equal(t, dec, []byte("hello, world"))
}

View File

@ -12,6 +12,8 @@ import (
"github.com/schollz/croc/src/models"
)
const TCP_BUFFER_SIZE = 1024 * 64
type roomInfo struct {
first comm.Comm
second comm.Comm
@ -163,7 +165,7 @@ func chanFromConn(conn net.Conn) chan []byte {
c := make(chan []byte)
go func() {
b := make([]byte, models.TCP_BUFFER_SIZE)
b := make([]byte, TCP_BUFFER_SIZE)
for {
n, err := conn.Read(b)