added some files
This commit is contained in:
1 parent
112b062571
commit
4897e8d307
7 files changed
+519
No files matched your search
@@ -0,0 +1,67 @@
|
|||||||
|
package encrypter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/aes"
|
||||||
|
"crypto/cipher"
|
||||||
|
"crypto/rand"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AESOFBEncrypter struct {
|
||||||
|
randomReader io.Reader
|
||||||
|
iv []byte
|
||||||
|
key []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAESOFBEncrypter() *AESOFBEncrypter {
|
||||||
|
ret := new(AESOFBEncrypter)
|
||||||
|
ret.randomReader = rand.Reader
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *AESOFBEncrypter) createSymetricKey(size int) ([]byte, error) {
|
||||||
|
key := make([]byte, size)
|
||||||
|
_, err := io.ReadFull(this.randomReader, key)
|
||||||
|
return key, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *AESOFBEncrypter) getCypherBlock() (cipher.Block, error) {
|
||||||
|
var err error
|
||||||
|
this.key, err = this.createSymetricKey(32)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return aes.NewCipher(this.key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *AESOFBEncrypter) createIV(block cipher.Block) (iv []byte, err error) {
|
||||||
|
return this.createSymetricKey(block.BlockSize())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *AESOFBEncrypter) createStreamMode(block cipher.Block) (stream cipher.Stream, err error) {
|
||||||
|
this.iv, err = this.createIV(block)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return cipher.NewOFB(block, this.iv), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *AESOFBEncrypter) createFileHandlerAndCypherBlock() (stream cipher.Stream, err error) {
|
||||||
|
cypherBlock, err := this.getCypherBlock()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return this.createStreamMode(cypherBlock)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *AESOFBEncrypter) EncryptReaderToWriter(clearInput io.Reader, encryptedOutput io.Writer) error {
|
||||||
|
stream, err := this.createFileHandlerAndCypherBlock()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
writer := &cipher.StreamWriter{S: stream, W: encryptedOutput}
|
||||||
|
if _, err := io.Copy(writer, clearInput); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
package encrypter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/aes"
|
||||||
|
"crypto/cipher"
|
||||||
|
"crypto/rand"
|
||||||
|
. "github.com/didiercrunch/ecrypto/helper"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewMockAESOFBEncrypter() *AESOFBEncrypter {
|
||||||
|
ret := new(AESOFBEncrypter)
|
||||||
|
ret.randomReader = NewMockRandomReader()
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreateSymetricKey(t *testing.T) {
|
||||||
|
c := NewMockAESOFBEncrypter()
|
||||||
|
key, e := c.createSymetricKey(512)
|
||||||
|
if e != nil {
|
||||||
|
t.Error(e)
|
||||||
|
} else if len(key) != 512 {
|
||||||
|
t.Error("bad key lenght")
|
||||||
|
} else if !reflect.DeepEqual(key, NewMockRandomReader().GetRandomBytes(512)) {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetCypherBlock(t *testing.T) {
|
||||||
|
c := NewMockAESOFBEncrypter()
|
||||||
|
if c.key != nil {
|
||||||
|
t.Error("expected nil key at this point")
|
||||||
|
}
|
||||||
|
block, err := c.getCypherBlock()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if block.BlockSize() != 16 {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
src := Range(16)
|
||||||
|
dst := make([]byte, 16)
|
||||||
|
expected := []byte{30, 248, 157, 9, 161, 60, 109, 82, 221, 152, 171, 167, 137,
|
||||||
|
239, 177, 191}
|
||||||
|
expectedKey := []byte{73, 233, 188, 33, 31, 118, 98, 81, 66, 120, 254, 85, 138, 36,
|
||||||
|
118, 80, 38, 83, 169, 57, 27, 61, 103, 122, 37, 164, 185, 40, 112, 66, 1, 50}
|
||||||
|
|
||||||
|
block.Encrypt(dst, src)
|
||||||
|
if !reflect.DeepEqual(dst, expected) {
|
||||||
|
t.Error("bad aes encryption", dst)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(c.key, expectedKey) {
|
||||||
|
t.Error("bad key", c.key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewEncrypter(t *testing.T) {
|
||||||
|
c := NewAESOFBEncrypter()
|
||||||
|
if c.randomReader != rand.Reader {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreateIV(t *testing.T) {
|
||||||
|
m := NewMockAESOFBEncrypter()
|
||||||
|
b, err := aes.NewCipher([]byte("example key 1234"))
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
iv, err := m.createIV(b)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
expt := NewMockRandomReader().GetRandomBytes(16)
|
||||||
|
if !reflect.DeepEqual(iv, expt) {
|
||||||
|
t.Error("bad iv", iv)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreateStreamMode(t *testing.T) {
|
||||||
|
m := NewMockAESOFBEncrypter()
|
||||||
|
if m.iv != nil {
|
||||||
|
t.Error("expected nil iv at first")
|
||||||
|
}
|
||||||
|
b, err := aes.NewCipher([]byte("example key 1234"))
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = m.createStreamMode(b)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
exptIv := NewMockRandomReader().GetRandomBytes(16)
|
||||||
|
if !reflect.DeepEqual(m.iv, exptIv) {
|
||||||
|
t.Error("bad iv", m.iv, " is not ", exptIv)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreateFileHandlerAndCypherBlock(t *testing.T) {
|
||||||
|
m := NewMockAESOFBEncrypter()
|
||||||
|
if m.iv != nil {
|
||||||
|
t.Error("expected nil iv at first")
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := m.createFileHandlerAndCypherBlock()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(m.key, NewMockRandomReader().GetRandomBytes(32)) {
|
||||||
|
t.Error("bad key", m.key)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(m.iv, NewMockRandomReader().GetRandomBytes(32 + 16)[32:32+16]) {
|
||||||
|
t.Error("bad iv", m.iv)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSimpleEncryptReaderToWriter(t *testing.T) {
|
||||||
|
reader := strings.NewReader("some plain text")
|
||||||
|
writer := NewMockIoWriter()
|
||||||
|
m := NewMockAESOFBEncrypter()
|
||||||
|
if err := m.EncryptReaderToWriter(reader, writer); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func decryptEncryptedTextWithAESAlgorithmAndOFBMode(key, iv, encryptedText []byte) (string, error) {
|
||||||
|
block, err := aes.NewCipher(key)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
stream := cipher.NewOFB(block, iv)
|
||||||
|
ret := make([]byte, len(encryptedText))
|
||||||
|
stream.XORKeyStream(ret, encryptedText)
|
||||||
|
return string(ret), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEncryptDecrypt(t *testing.T) {
|
||||||
|
reader := strings.NewReader("some plain text")
|
||||||
|
writer := NewMockIoWriter()
|
||||||
|
m := NewMockAESOFBEncrypter()
|
||||||
|
if err := m.EncryptReaderToWriter(reader, writer); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if plaintext2, err := decryptEncryptedTextWithAESAlgorithmAndOFBMode(m.key, m.iv, writer.Bytes()); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
} else if string(plaintext2) != "some plain text" {
|
||||||
|
t.Error("bad encryption/decryption process")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package encrypter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto"
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/sha512"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = sha512.New
|
||||||
|
|
||||||
|
type RsaSha512 struct {
|
||||||
|
PrivateKey *rsa.PrivateKey
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *RsaSha512) hashIOReader(input io.Reader) ([]byte, error) {
|
||||||
|
hashFunction := crypto.SHA512.New()
|
||||||
|
if _, err := io.Copy(hashFunction, input); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return hashFunction.Sum(nil), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *RsaSha512) SignStream(input io.Reader, rand io.Reader) ([]byte, error) {
|
||||||
|
hashed, err := this.hashIOReader(input)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return rsa.SignPSS(rand, this.PrivateKey, crypto.SHA512, hashed, nil)
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package encrypter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto"
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/sha512"
|
||||||
|
"fmt"
|
||||||
|
"github.com/didiercrunch/ecrypto/helper"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestHashIOReader(t *testing.T) {
|
||||||
|
rs := new(RsaSha512)
|
||||||
|
expt := "fabbbe22180f1f137cfdc9556d2570e775d1ae02a597ded43a72a40f9b485d500043b7b" +
|
||||||
|
"e128fb9fcd982b83159a0d99aa855a9e7cc4240c00dc01a9bdf8218d7"
|
||||||
|
input := bytes.NewBufferString("C is as portable as Stonehedge!!")
|
||||||
|
if hashValue, err := rs.hashIOReader(input); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
} else if fmt.Sprintf("%x", hashValue) != expt {
|
||||||
|
t.Errorf("Hash is not the same \n expected : %s\n"+
|
||||||
|
"results : %x ", expt, hashValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSignStream(t *testing.T) {
|
||||||
|
toSlice := func(data [sha512.Size]byte) []byte {
|
||||||
|
ret := make([]byte, sha512.Size)
|
||||||
|
for i, datum := range data {
|
||||||
|
ret[i] = datum
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
privateKey := helper.GetRSAPrivateKey(1024)
|
||||||
|
rs := &RsaSha512{privateKey}
|
||||||
|
input := bytes.NewBufferString("something to sign")
|
||||||
|
signature, err := rs.SignStream(input, helper.NewMockRandomReader())
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
hashed := toSlice(sha512.Sum512([]byte("something to sign")))
|
||||||
|
if err := rsa.VerifyPSS(&privateKey.PublicKey, crypto.SHA512, hashed, signature, nil); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
package helper
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rsa"
|
||||||
|
"encoding/binary"
|
||||||
|
"math/big"
|
||||||
|
"math/rand"
|
||||||
|
)
|
||||||
|
|
||||||
|
func B(x int64) *big.Int {
|
||||||
|
return big.NewInt(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
type MockRandomReader struct {
|
||||||
|
random *rand.Rand
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMockRandomReader() *MockRandomReader {
|
||||||
|
return &MockRandomReader{rand.New(rand.NewSource(99))}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *MockRandomReader) getNextFourRandomBytes() []byte {
|
||||||
|
ret := make([]byte, 4)
|
||||||
|
binary.LittleEndian.PutUint32(ret, uint32(this.random.Int31()))
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *MockRandomReader) Read(p []byte) (n int, err error) {
|
||||||
|
for i := 0; i < len(p); i += 4 {
|
||||||
|
copy(p[i:], this.getNextFourRandomBytes())
|
||||||
|
}
|
||||||
|
return len(p), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *MockRandomReader) GetRandomBytes(size int) []byte {
|
||||||
|
ret := make([]byte, size)
|
||||||
|
this.Read(ret)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
type MockIoWriter struct {
|
||||||
|
state []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMockIoWriter() *MockIoWriter {
|
||||||
|
return &MockIoWriter{make([]byte, 0, 1024)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *MockIoWriter) Write(p []byte) (n int, err error) {
|
||||||
|
this.state = append(this.state, p...)
|
||||||
|
return len(p), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *MockIoWriter) String() string {
|
||||||
|
return string(this.state)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *MockIoWriter) Length() int {
|
||||||
|
return len(this.state)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *MockIoWriter) Bytes() []byte {
|
||||||
|
return this.state
|
||||||
|
}
|
||||||
|
|
||||||
|
func Range(length int) []byte {
|
||||||
|
ret := make([]byte, length)
|
||||||
|
for i, _ := range ret {
|
||||||
|
ret[i] = byte(i)
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func FromRange(from, to int) []byte {
|
||||||
|
ret := make([]byte, to-from)
|
||||||
|
for i, _ := range ret {
|
||||||
|
ret[i] = byte(i + from)
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetRSAPublicKey(size int) *rsa.PublicKey {
|
||||||
|
return &GetRSAPrivateKey(size).PublicKey
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetRSAPrivateKey(size int) *rsa.PrivateKey {
|
||||||
|
key, err := rsa.GenerateKey(NewMockRandomReader(), size)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return key
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
package helper
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math/big"
|
||||||
|
"math/rand"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRange(t *testing.T) {
|
||||||
|
if !reflect.DeepEqual(Range(3), []byte{0, 1, 2}) {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFromRange(t *testing.T) {
|
||||||
|
if !reflect.DeepEqual(FromRange(3, 5), []byte{3, 4}) {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestB(t *testing.T) {
|
||||||
|
if !reflect.DeepEqual(B(3), big.NewInt(3)) {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMockIoWriter(t *testing.T) {
|
||||||
|
w := NewMockIoWriter()
|
||||||
|
fmt.Fprint(w, "something to write")
|
||||||
|
if !reflect.DeepEqual(w.Bytes(), []byte("something to write")) {
|
||||||
|
t.Fail()
|
||||||
|
} else if "something to write" != w.String() {
|
||||||
|
t.Fail()
|
||||||
|
} else if w.Length() != len("something to write") {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetRSAPublicKeyAndGetRSAPrivateKey(t *testing.T) {
|
||||||
|
privateKey := GetRSAPrivateKey(50)
|
||||||
|
if err := privateKey.Validate(); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
publicKey := GetRSAPublicKey(50)
|
||||||
|
if publicKey.E != privateKey.E || publicKey.N.Cmp(privateKey.N) != 0 {
|
||||||
|
t.Error("private and public keys do not match", publicKey.N, privateKey.N)
|
||||||
|
}
|
||||||
|
|
||||||
|
if publicKey.N.BitLen() != 50 {
|
||||||
|
t.Error("modulo has bad bit length")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetNextFourRandomBytes(t *testing.T) {
|
||||||
|
m := &MockRandomReader{rand.New(rand.NewSource(22))}
|
||||||
|
rb := m.getNextFourRandomBytes()
|
||||||
|
var expt []byte = []byte{233, 237, 107, 32}
|
||||||
|
if len(rb) != 4 {
|
||||||
|
t.Error("bad random length")
|
||||||
|
return
|
||||||
|
} else if !reflect.DeepEqual(expt, rb) {
|
||||||
|
t.Error("unexpect randome data")
|
||||||
|
}
|
||||||
|
|
||||||
|
rb = m.getNextFourRandomBytes()
|
||||||
|
expt = []byte{27, 131, 191, 20}
|
||||||
|
if len(rb) != 4 {
|
||||||
|
t.Error("bad random length")
|
||||||
|
return
|
||||||
|
} else if !reflect.DeepEqual(expt, rb) {
|
||||||
|
t.Error("unexpect randome data")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMockRandomReader(t *testing.T) {
|
||||||
|
m := NewMockRandomReader()
|
||||||
|
dump := make([]byte, 4*10+3)
|
||||||
|
if l, err := m.Read(dump); l != len(dump) || err != nil {
|
||||||
|
t.Error("that is very bad :(")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var expt []byte = []byte{73, 233, 188, 33, 31, 118, 98, 81, 66, 120, 254, 85, 138,
|
||||||
|
36, 118, 80, 38, 83, 169, 57, 27, 61, 103, 122, 37, 164, 185, 40, 112, 66, 1,
|
||||||
|
50, 185, 128, 156, 20, 8, 164, 37, 13, 182, 50, 175}
|
||||||
|
if !reflect.DeepEqual(dump, expt) {
|
||||||
|
t.Error("unexpected returned data\n", dump)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetRandomBytes(t *testing.T) {
|
||||||
|
rdBytes := NewMockRandomReader().GetRandomBytes(10)
|
||||||
|
expt := make([]byte, 10)
|
||||||
|
NewMockRandomReader().Read(expt)
|
||||||
|
if !reflect.DeepEqual(expt, rdBytes) {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Params struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
type Envelop struct {
|
||||||
|
err error
|
||||||
|
params *Params
|
||||||
|
}
|
||||||
|
|
||||||
|
func ZipIoReader(reader io.Reader) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func createEnvelop(reader io.Reader, writer io.WriteCloser, params *Params) error {
|
||||||
|
env := &Envelop{nil, params}
|
||||||
|
env.ZipDataForPayload()
|
||||||
|
env.CreatePayloadMetadata()
|
||||||
|
env.EncryptPayload()
|
||||||
|
env.CreateEnvelopMetadata()
|
||||||
|
env.EncryptPayloadKeyAndAddItToEncelop()
|
||||||
|
return env.getError()
|
||||||
|
}
|
||||||
Reference in new issue
Block a user