假如我们有一份很重要的文件想要从本地传输到远程客户端,因为并不想让别人看见我们传输的信息,所以需要使用某种手段将传输的数据保护起来,我们可以选择先将文件加密后再进行传输,别人收到之后再进行相应的解密操作。这种方式对于小文件来说问题倒不是很大,但是如果文件体积非常大,本地对文件进行加密和远程对文件进行解密花费的时间就会很长,这样的话时间效率就非常低了,如果我们可以对该文件边加密边传输,远程客户端也可以边接收边解密的话,时间效率就可以大幅度提升了。
下面我们来引入流加密解决上述问题,流加密有很多模式,例如 CFB
,CTR
,OFB
等。而流加密的核心就是异或操作,使用 XORKeyStream
就可以进行加解密了。
1 | package cipher |
因为加密解密肯定涉及到读写操作,所以我们用一个结构体 writer
实现 io.Writer
这个接口,里面封装了一个 io.Writer
和 cipher.Stream
,基本的思路就是将数据经过 cipher.Stream
的 XORKeyStream
方法写入 io.Writer
中。这里 buf
作为中间读操作和加密操作的缓存。
考虑到通用性,这里和下面我们使用 io.Writer
和 io.Writer
这样的接口进行抽象操作,而非使用具体的 Writer
或者 Reader
来代替。
1 | const bufSize = 32 * 1024 |
1 | func (w *writer) Write(b []byte) (int, error) { |
ReadFrom
方法使我们的 writer
不断从未加密的 io.Reader
中读取数据到 buf
中,再利用 XORKeyStream
将数据加密后写入自己的 io.Writer
中。
1 | func (w *writer) ReadFrom(r io.Reader) (n int64, err error) { |
在读方面,和写的时候类似,我们也在自己定义的结构体 reader
中包含一个 io.Reader
和 cipher.Stream
,基本思路也是从 io.Reader
中读取经过加密的数据,然后再用 cipher.Stream
的 XORKeyStream
方法解密。
1 | type reader struct { |
下面实现的 Read
方法利用 io.Reader
读取经过加密后的数据,再利用XORKeyStream
进行解密。
1 | func (r *reader) Read(b []byte) (int, error) { |
WriteTo
方法反复使用上面的 Read
方法将数据解密后写入 io.Writer
中直到结束。
1 | func (r *reader) WriteTo(w io.Writer) (n int64, err error) { |