started to implements the encryption process

This commit is contained in:
didier.amyot committed 2014-08-21 21:41:34 -07:00
1 parent e7f8e55e36
commit e8e1d66c1e
5 files changed
+300 -8

No files matched your search

+3
View File
@@ -1,3 +1,6 @@
*cover.out
/ecrypto
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
+25
View File
@@ -0,0 +1,25 @@
### public key
Note that any private key are a public key.
~~~
~~~
### private key
### cypher format
We use the `.cyp` file extension for the encrypted file. A .cyp is nothing
else than a zip file containing the following shit.
1. a `data.encrypted` containing the encrypted data
2. a `meta_data.yml` file containing the meta data of the encrypted file
* symetric encryption algorithm
* mode
* encrypted symetric key
* hash of the encrypted data (always use full for validation)
3. a 'signature' file with the signature of the `meta_data.yml` file
+68 -7
View File
@@ -1,16 +1,77 @@
package encrypter
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"github.com/didiercrunch/ecrypto/keys"
"io"
)
type Encrypter struct {
PublicKey keys.PublicKey
PrivateKey keys.PrivateKey
InputPath string
OutputPath string
type FileEncrypter struct {
PublicKey keys.PublicKey
PrivateKey keys.PrivateKey
InputPath string
OutputPath string
randomReader io.Reader
iv []byte
key []byte
}
func (this *Encrypter) Encrypt() error {
// encrypt file
func NewEncrypter() *FileEncrypter {
ret := new(FileEncrypter)
ret.randomReader = rand.Reader
return ret
}
func (this *FileEncrypter) createSymetricKey(size int) ([]byte, error) {
key := make([]byte, size)
_, err := io.ReadFull(this.randomReader, key)
return key, err
}
func (this *FileEncrypter) 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 *FileEncrypter) createIV(block cipher.Block) (iv []byte, err error) {
return this.createSymetricKey(block.BlockSize())
}
func (this *FileEncrypter) 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 *FileEncrypter) createFileHandlerAndCypherBlock() (stream cipher.Stream, err error) {
cypherBlock, err := this.getCypherBlock()
if err != nil {
return nil, err
}
return this.createStreamMode(cypherBlock)
}
func (this *FileEncrypter) encrypeReaderToWriter(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
}
func (this *FileEncrypter) Encrypt() error {
return nil
}
+204
View File
@@ -0,0 +1,204 @@
package encrypter
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"fmt"
"reflect"
"strings"
"testing"
)
var _ = fmt.Print
type mockIoWriter struct {
state []byte
}
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 newMockIoWriter() *mockIoWriter {
return &mockIoWriter{make([]byte, 0, 1024)}
}
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 createMockRandomData(length int) []byte {
ret := make([]byte, length)
for i, _ := range ret {
ret[i] = byte(i)
}
return ret
}
func NewMockEncrypter() *FileEncrypter {
ret := new(FileEncrypter)
mockRandomData := createMockRandomData(1024)
ret.randomReader = bytes.NewReader(mockRandomData)
return ret
}
func TestCreateSymetricKey(t *testing.T) {
c := NewMockEncrypter()
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, createMockRandomData(512)) {
t.Fail()
}
}
func TestGetCypherBlock(t *testing.T) {
c := NewMockEncrypter()
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 := createMockRandomData(16)
dst := make([]byte, 16)
expected := []byte{90, 110, 4, 87, 8, 251, 113, 150, 240, 46, 85, 61, 2, 195, 166, 146}
block.Encrypt(dst, src)
if !reflect.DeepEqual(dst, expected) {
t.Error("bad aes encryption")
}
if !reflect.DeepEqual(c.key, range_(32)) {
t.Error("bad key", c.key)
}
}
func TestNewEncrypter(t *testing.T) {
c := NewEncrypter()
if c.randomReader != rand.Reader {
t.Fail()
}
}
func TestCreateIV(t *testing.T) {
m := NewMockEncrypter()
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 := range_(16)
if !reflect.DeepEqual(iv, expt) {
t.Error("bad iv", iv)
}
}
func TestCreateStreamMode(t *testing.T) {
m := NewMockEncrypter()
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 := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
if !reflect.DeepEqual(m.iv, exptIv) {
t.Error("bad iv", m.iv)
}
}
func TestCreateFileHandlerAndCypherBlock(t *testing.T) {
m := NewMockEncrypter()
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, range_(32)) {
t.Error("bad key", m.key)
}
if !reflect.DeepEqual(m.iv, fromRange(32, 32+16)) {
t.Error("bad iv", m.iv)
}
}
func TestSimpleEncrypeReaderToWriter(t *testing.T) {
reader := strings.NewReader("some plain text")
writer := newMockIoWriter()
m := NewMockEncrypter()
if err := m.encrypeReaderToWriter(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 := NewMockEncrypter()
if err := m.encrypeReaderToWriter(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")
}
}
-1
View File
@@ -26,7 +26,6 @@ func (this *KeyGenerator) ensureDirectoryExists(dir string) error {
return errors.New(dir + " is not a directory")
}
return nil
}
func (this *KeyGenerator) saveKeyAsJSON(key interface{}, filepath string) error {