本文描述将某视频播放器ts文件解密后使用ffmpeg合成mp4文件,以本地播放,仅供学习。

1. 获取某视频播放器的视频m3u8文件;

2. 获取视频m3u8文件中的ts文件切片;

3. 获取encryptedVideoKey,并使用openssl以无填充aes-128-ebc解密,获得ts文件加解密的密钥;

4. 使用视频m3u8的iv及ts文件加解密的密钥,并使用openssl以aes-128-cbc无salt方式解密ts文件;

5. 使用ffmpeg将ts文件合成为mp4文件。

以上步骤的bash脚本示例如下:

#!/bin/bash

# 合成的mp4文件名,不含.mp4扩展名
video="8.8"

# m3u8文件中EXT-X-KEY:METHOD=AES-128行URI请求响应的encryptedVideoKey
encryptedVideoKey="8768ce7246034a05a4d9ffe7d6e419f2"

# m3u8文件中的IV
iv="0f004754ac8c09dfe568316770b1286f"

# m3u8文件中的ts文件总数
total="232"

merge() {
  local cipher_key=$1

  for (( i=0; i<=$total; i++ )); do
    curl 'https://examplevod.com/mda-nfmrbi46qeg7yrj2/mda-nfmrbi46qeg7yrj2.m3u8.'$i'.ts' \
      -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:143.0) Gecko/20100101 Firefox/143.0' \
      -H 'Accept: */*' \
      -H 'Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3' \
      -H 'Accept-Encoding: gzip, deflate, br, zstd' \
      -H 'Origin: https://studio.example.com' \
      -H 'DNT: 1' \
      -H 'Connection: keep-alive' \
      -H 'Referer: https://studio.example.com/' \
      -H 'Sec-Fetch-Dest: empty' \
      -H 'Sec-Fetch-Mode: cors' \
      -H 'Sec-Fetch-Site: cross-site' \
      -H 'Pragma: no-cache' \
      -H 'Cache-Control: no-cache' \
      -H 'TE: trailers' \
      -o $i.ts

    openssl aes-128-cbc -d -in $i.ts -out $i-d.ts -nosalt -iv $iv -K $cipher_key

    echo "file '$i-d.ts'" >> list.txt
  done

  ffmpeg -f concat -safe 0 -i list.txt -c copy $video.mp4

  rm -fr *.ts *.txt *.m3u8

}


# 密钥72Fhskjglp8qjpqx的十六进制串
hex_key="37324668736b6a676c7038716a707178"

# 将十六进制密文转换为二进制文件
echo -n "$encryptedVideoKey" | xxd -r -p > ciphertext.bin

# 使用OpenSSL解密(AES-128-ECB无填充模式)
openssl enc -d -aes-128-ecb -nopad -nosalt \
    -K "$hex_key" \
    -in ciphertext.bin -out decrypted.bin 2>/dev/null

# 将解密结果转换为十六进制
key=$(xxd -p -c 256 decrypted.bin | tr '[:lower:]' '[:upper:]')

# 清理临时文件
rm -f ciphertext.bin decrypted.bin

merge $key