Я пытаюсь реализовать, что считыватель собирается одновременно расшифровывать данные и проверять данные HMAC + SHA256
.
Расшифровывать полные данные как один блок и проверять их после работы.
Объем данных может быть довольно значительным, поэтому я не хочу хранить его в массиве.
Реализация ридера работает по большей части, но результатиз каждого 1024-го блока AES неверен .
func (r *mediaReader) Read(dst []byte) (n int, err error) {
if m := len(dst); m%r.cbc.BlockSize() != 0 {
m = (m / r.cbc.BlockSize()) * r.cbc.BlockSize()
dst = dst[:m]
}
n, err = r.limitedReader.Read(dst)
r.cbc.CryptBlocks(dst, dst)
tmp := r.fileLength - int64(n)
if tmp < 0 || err == io.EOF {
n += int(tmp)
}
r.total += n
r.fileLength -= int64(n)
r.hash.Write(dst)
if r.fileLength <= 0 || err == io.EOF {
//validate
mac := make([]byte, 10)
nn, rr := r.fullReader.Read(mac)
if rr != nil {
return n, rr
}
if nn != 10 {
return n, fmt.Errorf("not enougth data remaining")
}
if !hmac.Equal(mac, r.hash.Sum(nil)) {
return n, fmt.Errorf("invalid media hmac\n%v\n%v", r.hash.Sum(nil)[:10], mac)
}
//SUCCESS
return n, io.EOF
}
return n, err
}
* limitedReader
использует fullReader
и заканчивается 10 байтов до fullReader
.
Фрагмент mediaReader
создания:
h := hmac.New(sha256.New, macKey)
h.Write(iv)
cbc := cipher.NewCBCDecrypter(block, iv)
media := &io.LimitedReader{R: fullReader, N: length - 10}
return &mediaReader{
limitedReader: media,
fullReader: fullReader,
hash: h,
fileLength: fileLength,
cbc: cbc,
total: 0,
}
16384-16399;1 *1024* 16 (размер блока AES);16 неправильных байтов 32768-32783;2 *1024* 16 (размер блока AES);16 неправильных байтов 49152-49167;3 *1024* 16 (размер блока AES);16 неправильных байтов ...
Кто-нибудь понимает, что я делаю неправильно?