Closed benx1n closed 1 year ago
收到
经分析,此网站下载key的url的服务端至少验证了 User-Agent 的 Header信息:
以下请求能够得到正确的key信息:
req, err := http.NewRequest(http.MethodGet, `https://hls-auth.cloud.stream.co.jp/key?session_id=b4775a7e-56b8-4d8d-8d12-9ffeef9c7687&media_view_id=6PSgd6HXhgMFUMRL82hcIvisvcAh9e5j`, nil)
checkErr(err)
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36")
data, err := httputil.DumpRequest(req, false)
checkErr(err)
fmt.Println(string(data))
fmt.Println("===========")
resp, err := http.DefaultClient.Do(req)
checkErr(err)
data, err = io.ReadAll(resp.Body)
checkErr(err)
fmt.Println(string(data))
将user-agent的信息改成其他UA,例如 Mozilla/5.0 (iPhone; CPU iPhone OS 10_2 like Mac OS X) AppleWebKit/602.3.12 (KHTML, like Gecko) Mobile/14C92 MicroMessenger/6.5.16 NetType/WIFI Language/zh_CN
以下请求输出Forbiden:
req, err := http.NewRequest(http.MethodGet, `https://hls-auth.cloud.stream.co.jp/key?session_id=b4775a7e-56b8-4d8d-8d12-9ffeef9c7687&media_view_id=6PSgd6HXhgMFUMRL82hcIvisvcAh9e5j`, nil)
checkErr(err)
req.Header.Set("User-Agent", "Mozilla/5.0 (iPhone; CPU iPhone OS 10_2 like Mac OS X) AppleWebKit/602.3.12 (KHTML, like Gecko) Mobile/14C92 MicroMessenger/6.5.16 NetType/WIFI Language/zh_CN")
data, err := httputil.DumpRequest(req, false)
checkErr(err)
fmt.Println(string(data))
fmt.Println("===========")
resp, err := http.DefaultClient.Do(req)
checkErr(err)
data, err = io.ReadAll(resp.Body)
checkErr(err)
fmt.Println(string(data))
可能是session_id 或者 media_view_id 映射过UA信息之类的,具体实现取决于网站的服务端作者。
ok成功解决了,感谢您的解答
@benx1n hello, hls流是你们自己生成的吗
@benx1n hello, hls流是你们自己生成的吗
是直接在页面上抓到的
应该是ts文件解密出问题了 我这边手动解密ts文件,解密出来的ts文件是有pat表的
package main
import (
"crypto/aes"
"crypto/cipher"
"fmt"
"io/ioutil"
)
func main() {
ts, e := ioutil.ReadFile("test.ts")
b, e := ioutil.ReadFile("key")
fmt.Println("%x", b, len(b), e)
block, err := aes.NewCipher(b)
if err != nil {
fmt.Println(err)
}
iv := make([]byte, 16)
iv[15] = 1
blockMode := cipher.NewCBCDecrypter(block, iv)
result := make([]byte, len(ts))
blockMode.CryptBlocks(result, ts)
unPadding := int(result[len(result)-1])
result = result[:len(result)-unPadding]
ioutil.WriteFile("d_test.ts", result, 0666)
}
解密后的ts文件 d_test.zip
https://datatracker.ietf.org/doc/html/rfc8216#section-5.2
An EXT-X-KEY tag with a KEYFORMAT of "identity" that does not have an IV attribute indicates that the Media Sequence Number is to be used as the IV when decrypting a Media Segment, by putting its big-endian binary representation into a 16-octet (128-bit) buffer and padding (on the left) with zeros.
m3u8 文件里面 没有IV ,按照协议需要使用Media Sequence Number
看了m3u8d这块代码,实现上忽略了这块?
@yapingcat 你说得对,此处是一个bug
@benx1n 改了,试一下最新版本
没问题了,可以成功转码成mp4
m3u8链接是这个,我抹去了其中的session_id和media_view_id:m3u8链接 原视频地址是这里:链接 m3u8文件中是存在以下AES-128的key信息
#EXT-X-KEY:METHOD=AES-128,URI="https://hls-auth.cloud.stream.co.jp/key?session_id=123&123"
(与上方m3u8中的session_id,media_view_id相同) 如果手动下载key后是可以通过这个项目正确下载TSnilaoda/N_m3u8DL-CLI 但在m3u8d中报了invalid key size 9的错误 如果需要提供详细的session_id和media_view_id可以通过邮件发给您