mirror of
https://github.com/skidoodle/safebin.git
synced 2026-04-28 03:07:41 +02:00
71 lines
1.3 KiB
Go
71 lines
1.3 KiB
Go
package crypto
|
|
|
|
import (
|
|
"crypto/aes"
|
|
"crypto/cipher"
|
|
"crypto/sha256"
|
|
"encoding/base64"
|
|
"encoding/binary"
|
|
"io"
|
|
)
|
|
|
|
const (
|
|
GCMChunkSize = 64 * 1024
|
|
NonceSize = 12
|
|
)
|
|
|
|
func DeriveKey(r io.Reader) ([]byte, error) {
|
|
h := sha256.New()
|
|
if _, err := io.Copy(h, r); err != nil {
|
|
return nil, err
|
|
}
|
|
return h.Sum(nil)[:16], nil
|
|
}
|
|
|
|
func GetID(key []byte, ext string) string {
|
|
h := sha256.New()
|
|
h.Write(key)
|
|
h.Write([]byte(ext))
|
|
return base64.RawURLEncoding.EncodeToString(h.Sum(nil)[:9])
|
|
}
|
|
|
|
type GCMStreamer struct {
|
|
AEAD cipher.AEAD
|
|
}
|
|
|
|
func NewGCMStreamer(key []byte) (*GCMStreamer, error) {
|
|
b, err := aes.NewCipher(key)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
g, err := cipher.NewGCM(b)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &GCMStreamer{AEAD: g}, nil
|
|
}
|
|
|
|
func (g *GCMStreamer) EncryptStream(dst io.Writer, src io.Reader) error {
|
|
buf := make([]byte, GCMChunkSize)
|
|
var chunkIdx uint64 = 0
|
|
for {
|
|
n, err := io.ReadFull(src, buf)
|
|
if n > 0 {
|
|
nonce := make([]byte, NonceSize)
|
|
binary.BigEndian.PutUint64(nonce[4:], chunkIdx)
|
|
ciphertext := g.AEAD.Seal(nil, nonce, buf[:n], nil)
|
|
if _, werr := dst.Write(ciphertext); werr != nil {
|
|
return werr
|
|
}
|
|
chunkIdx++
|
|
}
|
|
if err == io.EOF || err == io.ErrUnexpectedEOF {
|
|
break
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|