cryptowrap

package module
v0.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 14, 2022 License: MIT Imports: 15 Imported by: 0

README

= cryptowrap image:https://godoc.org/github.com/Djarvur/go-cryptowrap?status.svg["GoDoc",link="http://godoc.org/github.com/Djarvur/go-cryptowrap"] image:https://github.com/Djarvur/go-cryptowrap/workflows/Test/badge.svg?branch=master["Build Status"] image:https://coveralls.io/repos/Djarvur/go-cryptowrap/badge.svg?branch=master&service=github["Coverage Status",link="https://coveralls.io/github/Djarvur/go-cryptowrap?branch=master"]

JSON/Gob/MsgPack/CBOR-based Marshaler/Unmarshaler with AES/RSA encryption

cryptowrap.Wrapper is a struct with custom JSON/Gob/Binary marshaler and unmarshaler.

Marshaler will encrypt Payload with AES using first value from Keys as a key and provided IV as an initialisation vector.
Random string will be used if no IV provided.

Actual AES form will be chosen based on first Keys value length.

Serialised data are protected by checksum.

Unmarshaler will decrypt Payload with the Keys provided.
Keys will be tried one by one until success decryption.
Success means checksum check satisfied.
ErrUndecryptable will be returned in case no one key is suitable.

RSA Marshaler will encrypt Payload with RSA using public key provided as a key using RSA-OAEP.

RSA Unmarshaler will decrypt Payload with the private keys provided.
Keys will be tried one by one until success decryption.
ErrUndecryptable will be returned in case no one key is suitable.

== Example

[source]
----
	type toPass struct {
		Insecure string
		Secure   cryptowrap.Wrapper
	}

	type toPassSecure struct {
		Field string
	}

	key := []byte("0123456789ABCDEF")

	srcSecure := toPassSecure{"world!"}

	src := toPass{
		Insecure: "hello",
		Secure: cryptowrap.Wrapper{
			Keys:    [][]byte{key},
			Payload: &srcSecure,
		},
	}

	data, err := json.Marshal(&src)
	if err != nil {
		panic(err)
	}

	//	var onTheGo interface{}
	//
	//	err = json.Unmarshal(data, &onTheGo)
	//	if err != nil {
	//		panic(err)
	//	}
	//
	//	log.Printf("payload is encrypted: %v\n", onTheGo)

	var dstSecure toPassSecure

	dst := toPass{
		Secure: cryptowrap.Wrapper{
			Keys:    [][]byte{key},
			Payload: &dstSecure,
		},
	}

	err = json.Unmarshal(data, &dst)
	if err != nil {
		panic(err)
	}

	fmt.Printf("%v\n", dst.Secure.Payload.(*toPassSecure).Field)
	// Output: world!
----

== Benchmark

Raw is no-encryption wrapper, just to compare with crypto.

[source]
----
$go test -bench=. -benchmem
goos: darwin
goarch: amd64
pkg: github.com/Djarvur/cryptowrap
cpu: Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
BenchmarkRawJSON-16                     372861      3187 ns/op	     520 B/op    14 allocs/op
BenchmarkRawGob-16                       28830     41712 ns/op	   10299 B/op   255 allocs/op
BenchmarkRawMsgp-16                     180513      6548 ns/op	    4808 B/op    47 allocs/op
BenchmarkRawCBOR-16                     562105      2152 ns/op	     536 B/op    14 allocs/op
BenchmarkWrapperJSON128-16               59504     20185 ns/op	    4166 B/op    59 allocs/op
BenchmarkWrapperJSON256-16               52342     22729 ns/op	    4815 B/op    59 allocs/op
BenchmarkWrapperJSON128Compress-16         682   1497239 ns/op	13457840 B/op    78 allocs/op
BenchmarkWrapperJSON256Compress-16         775   1504389 ns/op	13554405 B/op    79 allocs/op
BenchmarkWrapperGob128-16                 7628    147049 ns/op	   39575 B/op   890 allocs/op
BenchmarkWrapperGob256-16                 7840    147722 ns/op	   40182 B/op   890 allocs/op
BenchmarkWrapperGob128Compress-16          805   1390948 ns/op	10850581 B/op   902 allocs/op
BenchmarkWrapperGob256Compress-16          814   1406234 ns/op	11005549 B/op   902 allocs/op
BenchmarkWrapperMsgp128-16               44914     26535 ns/op	   19976 B/op   176 allocs/op
BenchmarkWrapperMsgp256-16               44246     26958 ns/op	   20424 B/op   176 allocs/op
BenchmarkWrapperMsgp128Compress-16         736   1533282 ns/op	13650652 B/op   186 allocs/op
BenchmarkWrapperMsgp256Compress-16         754   1530784 ns/op	13661366 B/op   187 allocs/op
BenchmarkWrapperCBOR128-16               50212     23973 ns/op	   15986 B/op   148 allocs/op
BenchmarkWrapperCBOR256-16               47757     24615 ns/op	   16434 B/op   148 allocs/op
BenchmarkWrapperCBOR128Compress-16         738   1577503 ns/op	14044718 B/op   161 allocs/op
BenchmarkWrapperCBOR256Compress-16         748   1560975 ns/op	13797760 B/op   162 allocs/op
BenchmarkWrapperRSAJSON2048-16             520   2304840 ns/op	   34519 B/op   154 allocs/op
BenchmarkWrapperRSAJSON4096-16              92  12877419 ns/op	   82464 B/op   169 allocs/op
BenchmarkWrapperRSAJSON2048Compress-16     297   4001751 ns/op	14613248 B/op   180 allocs/op
BenchmarkWrapperRSAJSON4096Compress-16      78  14838815 ns/op	15035632 B/op   193 allocs/op
BenchmarkWrapperRSAGob4096-16               87  13132682 ns/op	  120159 B/op  1038 allocs/op
BenchmarkWrapperRSAGob4096Compress-16       79  14555753 ns/op	12019596 B/op  1054 allocs/op
BenchmarkWrapperRSAMsgp2048-16             524   2316920 ns/op	   49494 B/op   253 allocs/op
BenchmarkWrapperRSAMsgp4096-16              92  12919625 ns/op	   97117 B/op   267 allocs/op
BenchmarkWrapperRSAMsgp2048Compress-16     290   4051183 ns/op	14760536 B/op   269 allocs/op
BenchmarkWrapperRSAMsgp4096Compress-16      78  14687531 ns/op	13755031 B/op   282 allocs/op
BenchmarkWrapperRSACBOR2048-16             522   2302611 ns/op	   45549 B/op   225 allocs/op
BenchmarkWrapperRSACBOR4096-16              90  12916202 ns/op	   93195 B/op   240 allocs/op
BenchmarkWrapperRSACBOR2048Compress-16     302   3979701 ns/op	14500539 B/op   244 allocs/op
BenchmarkWrapperRSACBOR4096Compress-16      79  14646619 ns/op	14542632 B/op   257 allocs/op
PASS
ok  	github.com/Djarvur/cryptowrap	51.179s
----

Documentation

Overview

Package cryptowrap JSON/Gob/MsgPack-based Marshaler/Unmarshaler with AES encryption

Package cryptowrap JSON/Gob/MsgPack-based Marshaler/Unmarshaler with AES encryption

Example (Cbor)
type toPass struct {
	Insecure string
	Secure   cryptowrap.Wrapper
}

type toPassSecure struct {
	Field string
}

key := []byte("0123456789ABCDEF")

srcSecure := toPassSecure{"hello world!"}

src := toPass{
	Insecure: "hello",
	Secure: cryptowrap.Wrapper{
		Keys:    [][]byte{key},
		Payload: &srcSecure,
	},
}

data, err := cbor.Marshal(&src)
if err != nil {
	panic(err)
}

var dstSecure toPassSecure

dst := toPass{
	Secure: cryptowrap.Wrapper{
		Keys:    [][]byte{key},
		Payload: &dstSecure,
	},
}

err = cbor.Unmarshal(data, &dst)
if err != nil {
	panic(err)
}

fmt.Printf("%v\n", dst.Secure.Payload.(*toPassSecure).Field)
Output:

hello world!
Example (Direct)
package main

import (
	"encoding/json"
	"fmt"

	"github.com/Djarvur/cryptowrap"
)

func main() {
	key := []byte("0123456789ABCDEF")

	src := "hello!"

	data, err := json.Marshal(&cryptowrap.Wrapper{Keys: [][]byte{key}, Payload: &src})
	if err != nil {
		panic(err)
	}

	//	var onTheGo interface{}
	//
	//	err = json.Unmarshal(data, &onTheGo)
	//	if err != nil {
	//		panic(err)
	//	}
	//
	//	log.Printf("payload is encrypted: %v\n", onTheGo)

	var dst string

	err = json.Unmarshal(data, &cryptowrap.Wrapper{Keys: [][]byte{key}, Payload: &dst})
	if err != nil {
		panic(err)
	}

	fmt.Printf("%v\n", dst)
}
Output:

hello!
Example (Embeded)
package main

import (
	"encoding/json"
	"fmt"

	"github.com/Djarvur/cryptowrap"
)

func main() {
	type toPass struct {
		Insecure string
		Secure   cryptowrap.Wrapper
	}

	type toPassSecure struct {
		Field string
	}

	key := []byte("0123456789ABCDEF")

	srcSecure := toPassSecure{"world!"}

	src := toPass{
		Insecure: "hello",
		Secure: cryptowrap.Wrapper{
			Keys:    [][]byte{key},
			Payload: &srcSecure,
		},
	}

	data, err := json.Marshal(&src)
	if err != nil {
		panic(err)
	}

	//	var onTheGo interface{}
	//
	//	err = json.Unmarshal(data, &onTheGo)
	//	if err != nil {
	//		panic(err)
	//	}
	//
	//	log.Printf("payload is encrypted: %v\n", onTheGo)

	var dstSecure toPassSecure

	dst := toPass{
		Secure: cryptowrap.Wrapper{
			Keys:    [][]byte{key},
			Payload: &dstSecure,
		},
	}

	err = json.Unmarshal(data, &dst)
	if err != nil {
		panic(err)
	}

	fmt.Printf("%v\n", dst.Secure.Payload.(*toPassSecure).Field)
}
Output:

world!
Example (Gob)
package main

import (
	"bytes"
	"encoding/gob"
	"fmt"

	"github.com/Djarvur/cryptowrap"
)

func main() {
	type toPass struct {
		Insecure string
		Secure   cryptowrap.Wrapper
	}

	type toPassSecure struct {
		Field string
	}

	key := []byte("0123456789ABCDEF")

	srcSecure := toPassSecure{"hello world!"}

	src := toPass{
		Insecure: "hello",
		Secure: cryptowrap.Wrapper{
			Keys:    [][]byte{key},
			Payload: &srcSecure,
		},
	}

	gob.Register(&srcSecure)

	var b bytes.Buffer

	err := gob.NewEncoder(&b).Encode(&src)
	if err != nil {
		panic(err)
	}

	data := b.Bytes()

	var dstSecure toPassSecure

	dst := toPass{
		Secure: cryptowrap.Wrapper{
			Keys:    [][]byte{key},
			Payload: &dstSecure,
		},
	}

	err = gob.NewDecoder(bytes.NewBuffer(data)).Decode(&dst)
	if err != nil {
		panic(err)
	}

	fmt.Printf("%v\n", dst.Secure.Payload.(*toPassSecure).Field)
}
Output:

hello world!
Example (Msgpack)
package main

import (
	"bytes"
	"fmt"

	"github.com/Djarvur/cryptowrap"
	"github.com/ugorji/go/codec"
)

func main() {
	type toPass struct {
		Insecure string
		Secure   cryptowrap.Wrapper
	}

	type toPassSecure struct {
		Field string
	}

	key := []byte("0123456789ABCDEF")

	srcSecure := toPassSecure{"hello world!"}

	src := toPass{
		Insecure: "hello",
		Secure: cryptowrap.Wrapper{
			Keys:    [][]byte{key},
			Payload: &srcSecure,
		},
	}

	var b bytes.Buffer

	err := codec.NewEncoder(&b, new(codec.MsgpackHandle)).Encode(&src)
	if err != nil {
		panic(err)
	}

	data := b.Bytes()

	var dstSecure toPassSecure

	dst := toPass{
		Secure: cryptowrap.Wrapper{
			Keys:    [][]byte{key},
			Payload: &dstSecure,
		},
	}

	err = codec.NewDecoderBytes(data, new(codec.MsgpackHandle)).Decode(&dst)
	if err != nil {
		panic(err)
	}

	fmt.Printf("%v\n", dst.Secure.Payload.(*toPassSecure).Field)
}
Output:

hello world!
Example (Rsa)
package main

import (
	"crypto/rand"
	"crypto/rsa"
	"encoding/json"
	"fmt"

	"github.com/Djarvur/cryptowrap"
)

func main() {
	type toPass struct {
		Insecure string
		Secure   cryptowrap.WrapperRSA
	}

	type toPassSecure struct {
		Field string
	}

	key, err := rsa.GenerateKey(rand.Reader, 2048)
	if err != nil {
		panic(err)
	}

	srcSecure := toPassSecure{"world!"}

	src := toPass{
		Insecure: "hello",
		Secure: cryptowrap.WrapperRSA{
			EncKey:  &key.PublicKey,
			Payload: &srcSecure,
		},
	}

	data, err := json.Marshal(&src)
	if err != nil {
		panic(err)
	}

	var dstSecure toPassSecure

	dst := toPass{
		Secure: cryptowrap.WrapperRSA{
			DecKeys: []*rsa.PrivateKey{key},
			Payload: &dstSecure,
		},
	}

	err = json.Unmarshal(data, &dst)
	if err != nil {
		panic(err)
	}

	fmt.Printf("%v\n", dst.Secure.Payload.(*toPassSecure).Field)
}
Output:

world!

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ErrUndecryptable = errors.New("data could not be decrypted")
	ErrNoKey         = errors.New("key has to be provided")
)

Errors might be returned. They will be wrapped with stacktrace at least, of course.

Functions

This section is empty.

Types

type Wrapper

type Wrapper struct {
	Keys     [][]byte
	IV       []byte
	Payload  interface{}
	Compress bool
}

Wrapper is a struct with custom JSON/Gob/Binary marshaler and unmarshaler.

Marshaler will encrypt Payload with AES using first value from Keys as a key and provided IV as an initialisation vector. Random string will be used if no IV provided.

Actual AES form will be chosen based on first Keys value length.

Serialised data are protected by checksum.

Unmarshaler will decrypt Payload with the Keys provided. Keys will be tryied one by one until success decryption. Success means checksum check satisfied. ErrUndecryptable will be returned in case no one key is suitable.

If Compress is true serialized Payload wil be compressed with LZ4.

func (*Wrapper) GobDecode added in v0.1.1

func (w *Wrapper) GobDecode(data []byte) error

GobDecode is a custom unmarshaler.

func (*Wrapper) GobEncode added in v0.1.1

func (w *Wrapper) GobEncode() ([]byte, error)

GobEncode is a custom marshaler.

func (*Wrapper) MarshalBinary added in v0.1.1

func (w *Wrapper) MarshalBinary() (data []byte, err error)

MarshalBinary is a custom marshaler to be used with MsgPack (github.com/ugorji/go/codec).

func (*Wrapper) MarshalJSON

func (w *Wrapper) MarshalJSON() ([]byte, error)

MarshalJSON is a custom marshaler.

func (*Wrapper) UnmarshalBinary added in v0.1.1

func (w *Wrapper) UnmarshalBinary(data []byte) error

UnmarshalBinary is a custom unmarshaler to be used with MsgPack (github.com/ugorji/go/codec).

func (*Wrapper) UnmarshalJSON

func (w *Wrapper) UnmarshalJSON(data []byte) error

UnmarshalJSON is a custom unmarshaler.

type WrapperRSA added in v0.2.0

type WrapperRSA struct {
	DecKeys  []*rsa.PrivateKey
	EncKey   *rsa.PublicKey
	Hash     hash.Hash
	Label    []byte
	Payload  interface{}
	Compress bool
}

WrapperRSA is a struct with custom JSON/Gob/Binary marshaler and unmarshaler.

Marshaler will encrypt Payload with RSA using EncKey as a public key. and hash function provided in Hash. sha256.New() will be used if no Hash provided.

Unmarshaler will decrypt Payload with the DecKeys provided. Keys will be tryied one by one until success decryption. ErrUndecryptable will be returned in case no one key is suitable.

Label must be the same for Marshaling and Umarshaling. If no label provided empty one is used.

If Compress is true serialized Payload wil be compressed with LZ4.

Note: there is a limit for the length of data could be encrypted with RSA: The message must be no longer than the length of the public modulus minus twice the hash length, minus a further 2. See https://golang.org/pkg/crypto/rsa/#EncryptOAEP for details (there no much though).

func (*WrapperRSA) GobDecode added in v0.2.0

func (w *WrapperRSA) GobDecode(data []byte) error

GobDecode is a custom unmarshaler.

func (*WrapperRSA) GobEncode added in v0.2.0

func (w *WrapperRSA) GobEncode() ([]byte, error)

GobEncode is a custom marshaler.

func (*WrapperRSA) MarshalBinary added in v0.2.0

func (w *WrapperRSA) MarshalBinary() (data []byte, err error)

MarshalBinary is a custom marshaler to be used with MsgPack (github.com/ugorji/go/codec).

func (*WrapperRSA) MarshalJSON added in v0.2.0

func (w *WrapperRSA) MarshalJSON() ([]byte, error)

MarshalJSON is a custom marshaler.

func (*WrapperRSA) UnmarshalBinary added in v0.2.0

func (w *WrapperRSA) UnmarshalBinary(data []byte) error

UnmarshalBinary is a custom unmarshaler to be used with MsgPack (github.com/ugorji/go/codec).

func (*WrapperRSA) UnmarshalJSON added in v0.2.0

func (w *WrapperRSA) UnmarshalJSON(data []byte) error

UnmarshalJSON is a custom unmarshaler.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL