我正在嘗試通過io.ReadFull以塊的形式處理數據以節省內存來下載和解密 HLS 流:為簡單起見,省略了不相關的代碼部分。func main() { f, _ := os.Create(out.ts) for _, v := range mediaPlaylist { resp, _ := http.Get(v.URI) for { r, err := decryptHLS(key, iv, resp.Body) if err != nil && err == io.EOF { break else if err != nil && err != io.ErrUnexpectedEOF { panic(err) } io.Copy(f, r) } }}func decryptHLS(key []byte, iv []byte, r io.Reader) (io.Reader, error) { block, _ := aes.NewCipher(key) buf := make([]byte, 8192) mode := cipher.NewCBCDecrypter(block, iv) n, err := io.ReadFull(r, buf) if err != nil && err != io.ErrUnexpectedEOF { return nil, err } mode.CryptBlocks(buf, buf) return bytes.NewReader(buf[:n]), err}起初,這似乎可以正常工作,因為文件大小正確且下載過程中沒有錯誤,但視頻已損壞。不完全因為該文件仍被識別為視頻,但圖像和聲音失真。如果我更改要使用的代碼ioutil.ReadAll,最終的視頻文件將不再損壞:func main() { f, _ := os.Create(out.ts) for _, v := range mediaPlaylist { resp, _ := http.Get(v.URI) segment, _ := ioutil.ReadAll(resp.Body) r, _ := decryptHLS(key, iv, &segment) io.Copy(f, r) }}func decryptHLS(key []byte, iv []byte, s *[]byte) io.Reader { block, _ := aes.NewCipher(key) mode := cipher.NewCBCDecrypter(block, iv) mode.CryptBlocks(*s, *s) return bytes.NewReader(*s)}任何想法為什么它在將整個段讀入內存時正常工作,而不是io.ReadFull在塊中使用和處理它時?
1 回答

忽然笑
TA貢獻1806條經驗 獲得超5個贊
在內部, CBCDecrypter 會復制您的iv
,因此后續塊以初始 IV 開頭,而不是由先前解密改變的那個。
創建一次解密器,您應該能夠繼續重復使用它來逐塊解密(假設塊大小是此加密算法預期的塊大小的倍數)。
- 1 回答
- 0 關注
- 106 瀏覽
添加回答
舉報
0/150
提交
取消