Skip to content

Commit 8b1d14a

Browse files
author
Soumo Sarkar
committed
encryption and decryption of file
1 parent 5e5c51c commit 8b1d14a

File tree

8 files changed

+163
-31
lines changed

8 files changed

+163
-31
lines changed

crypto.go

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package main
2+
3+
import (
4+
"crypto/aes"
5+
"crypto/cipher"
6+
"crypto/rand"
7+
"io"
8+
)
9+
10+
func newEncryptionKey() []byte {
11+
keyBuf := make([]byte, 32)
12+
io.ReadFull(rand.Reader, keyBuf)
13+
return keyBuf
14+
}
15+
16+
func copyDecrypt(key []byte, src io.Reader, dst io.Writer) (int, error) {
17+
block, err := aes.NewCipher(key)
18+
if err != nil {
19+
return 0, err
20+
}
21+
22+
/*
23+
Read the IV from the given io.Reader
24+
in our case which should be the block.BlockSize bytes we read.
25+
*/
26+
iv := make([]byte, block.BlockSize())
27+
if _, err := src.Read(iv); err != nil {
28+
return 0, err
29+
}
30+
31+
var (
32+
buf = make([]byte, 32*1024)
33+
stream = cipher.NewCTR(block, iv)
34+
nw = block.BlockSize()
35+
)
36+
37+
for {
38+
n, err := src.Read(buf)
39+
if n > 0 {
40+
stream.XORKeyStream(buf, buf[:n])
41+
n, err := dst.Write(buf[:n])
42+
if err != nil {
43+
return 0, err
44+
}
45+
nw += n
46+
}
47+
if err == io.EOF {
48+
break
49+
}
50+
if err != nil {
51+
return 0, err
52+
}
53+
}
54+
55+
return nw, nil
56+
}
57+
58+
func copyEncrypt(key []byte, src io.Reader, dst io.Writer) (int, error) {
59+
block, err := aes.NewCipher(key)
60+
if err != nil {
61+
return 0, err
62+
}
63+
64+
iv := make([]byte, block.BlockSize()) // 16 bytes
65+
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
66+
return 0, err
67+
}
68+
69+
// prepend the IV to the file
70+
if _, err := dst.Write(iv); err != nil {
71+
return 0, err
72+
}
73+
74+
var (
75+
buf = make([]byte, 32*1024)
76+
stream = cipher.NewCTR(block, iv)
77+
nw = block.BlockSize()
78+
)
79+
80+
for {
81+
n, err := src.Read(buf)
82+
if n > 0 {
83+
stream.XORKeyStream(buf, buf[:n])
84+
n, err := dst.Write(buf[:n])
85+
if err != nil {
86+
return 0, err
87+
}
88+
nw += n
89+
}
90+
91+
if err == io.EOF {
92+
break
93+
}
94+
if err != nil {
95+
return 0, err
96+
}
97+
}
98+
99+
return nw, nil
100+
}

crypto_test.go

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
"testing"
7+
)
8+
9+
func TestCopyEncryptDecrypt(t *testing.T) {
10+
payload := "Foo not bar"
11+
src := bytes.NewReader([]byte(payload))
12+
dst := new(bytes.Buffer)
13+
key := newEncryptionKey()
14+
_, err := copyEncrypt(key, src, dst)
15+
if err != nil {
16+
t.Error(err)
17+
}
18+
19+
fmt.Println(len(payload))
20+
fmt.Println(len(dst.String()))
21+
22+
out := new(bytes.Buffer)
23+
nw, err := copyDecrypt(key, dst, out)
24+
if err != nil {
25+
t.Error(err)
26+
}
27+
28+
if nw != 16+len(payload) {
29+
t.Fail()
30+
}
31+
32+
if out.String() != payload {
33+
t.Errorf("decryption failed!")
34+
}
35+
}

go.mod

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ module github.com/SuperSection/FileStorage
22

33
go 1.22.5
44

5+
require github.com/stretchr/testify v1.9.0
6+
57
require (
68
github.com/davecgh/go-spew v1.1.1 // indirect
79
github.com/pmezard/go-difflib v1.0.0 // indirect
8-
github.com/stretchr/testify v1.9.0 // indirect
910
gopkg.in/yaml.v3 v3.0.1 // indirect
1011
)

go.sum

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
44
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
55
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
66
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
7+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
78
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
89
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
910
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

main.go

+16-17
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
package main
22

33
import (
4-
"fmt"
5-
"io"
4+
"bytes"
65
"log"
76
"time"
87

@@ -20,6 +19,7 @@ func makeServer(listenAddr string, nodes ...string) *FileServer {
2019
tcpTransport := p2p.NewTCPTransport(tcpOptions)
2120

2221
fileServerOptions := FileServerOptions{
22+
EncKey: newEncryptionKey(),
2323
StorageRoot: listenAddr + "_network",
2424
PathTransformFunc: CASPathTransformFunc,
2525
Transport: tcpTransport,
@@ -47,19 +47,18 @@ func main() {
4747
go s2.Start()
4848
time.Sleep(2 * time.Second)
4949

50-
// data := bytes.NewReader([]byte("my big data file here!"))
51-
// s2.Store("cool_picture.jpg", data)
52-
// time.Sleep(time.Millisecond * 500)
53-
54-
r, err := s2.Get("cool_picture.jpg")
55-
if err != nil {
56-
log.Fatal(err)
57-
}
58-
59-
b, err := io.ReadAll(r)
60-
if err != nil {
61-
log.Fatal(err)
62-
}
63-
64-
fmt.Println(string(b))
50+
data := bytes.NewReader([]byte("my big data file here!"))
51+
s2.Store("cool_picture.jpg", data)
52+
53+
// r, err := s2.Get("cool_picture.jpg")
54+
// if err != nil {
55+
// log.Fatal(err)
56+
// }
57+
//
58+
// b, err := io.ReadAll(r)
59+
// if err != nil {
60+
// log.Fatal(err)
61+
// }
62+
//
63+
// fmt.Println(string(b))
6564
}

p2p/encoding.go

-1
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,3 @@ func (dec *DefaultDecoder) Decode(r io.Reader, msg *RPC) error {
4141

4242
return nil
4343
}
44-

p2p/tcp_transport_test.go

+6-10
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,13 @@ import (
77
)
88

99
func TestTCPTransport(t *testing.T) {
10-
tcpOptions := TCPTransportOptions{
11-
ListenAddress: ":4001",
12-
Decoder: &DefaultDecoder{},
10+
opts := TCPTransportOptions{
11+
ListenAddress: ":3000",
1312
HandshakeFunc: NOPHandshakeFunc,
13+
Decoder: &DefaultDecoder{},
1414
}
15+
tr := NewTCPTransport(opts)
16+
assert.Equal(t, tr.ListenAddr, ":3000")
1517

16-
tr := NewTCPTransport(tcpOptions)
17-
assert.Equal(t, tr.ListenAddress, ":4001")
18-
19-
// Server
2018
assert.Nil(t, tr.ListenAndAccept())
21-
22-
select {}
23-
}
19+
}

server.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
)
1515

1616
type FileServerOptions struct {
17+
EncKey []byte
1718
StorageRoot string
1819
PathTransformFunc PathTransformFunc
1920
Transport p2p.Transport
@@ -144,7 +145,7 @@ func (server *FileServer) Store(key string, r io.Reader) error {
144145
msg := Message{
145146
Payload: MessageStoreFile{
146147
Key: key,
147-
Size: size,
148+
Size: size + 16,
148149
},
149150
}
150151

@@ -157,7 +158,7 @@ func (server *FileServer) Store(key string, r io.Reader) error {
157158
// TODO: use a multiwriter here.
158159
for _, peer := range server.peers {
159160
peer.Send([]byte{p2p.IncomingStream})
160-
n, err := io.Copy(peer, fileBuffer)
161+
n, err := copyEncrypt(server.EncKey, fileBuffer, peer)
161162
if err != nil {
162163
return err
163164
}

0 commit comments

Comments
 (0)