【问题标题】:Decrypting And Combining .ts Audio Files with .m3u8使用 .m3u8 解密和组合 .ts 音频文件
【发布时间】:2016-03-18 01:35:33
【问题描述】:

我有几千个带有 .key 和 .m3u8 文件的 .ts AES-128 加密音频文件。

密钥文件只包含一个由 44 个字符组成的密钥。 .m3ud 文件似乎是某种类型的播放列表。

#EXTM3U
#EXT-X-ALLOW-CACHE:NO
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-KEY:METHOD=AES-128,URI="http://localhost:[port]/hls/keys/nax_9781843794066.key"
#EXTINF:10,
http://localhost:[port]/filesequence0000000.ts
#EXTINF:10,
etc...

请注意,.ts 文件的关键 URI 和路径现在都是错误的。

环顾四周,似乎 ffmpeg 可能适用于这种格式。但我不确定语法。

如何解密和合并这些文件?

我一直在尝试修复播放列表语法并弄清楚如何使用 ffmpeg 并得到了。

ffmpeg -i nax_9781843794066.m3u8 -c copy output.ts
ffmpeg version N-77197-gdf2ce13 Copyright (c) 2000-2015 the FFmpeg developers
built with gcc 5.2.0 (GCC)
configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libdcadec --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzimg --enable-lzma --enable-decklink --enable-zlib
libavutil      55. 10.100 / 55. 10.100
libavcodec     57. 17.100 / 57. 17.100
libavformat    57. 19.100 / 57. 19.100
libavdevice    57.  0.100 / 57.  0.100
libavfilter     6. 20.100 /  6. 20.100
libswscale      4.  0.100 /  4.  0.100
libswresample   2.  0.101 /  2.  0.101
libpostproc    54.  0.100 / 54.  0.100
[hls,applehttp @ 0000003e6348a660] Error when loading first segment 'filesequence0000000.ts'
nax_9781843794066.m3u8: Invalid data found when processing input

filesequence0000000.ts 是第一个文件,在同一个文件夹中。我无法判断这是加密问题还是其他问题。

这是关键文件,如果重要的话:MoOoNvcKlThWBm2T+VzYq9QKZLw7MFUqSyLYjiwquTQ=

【问题讨论】:

  • 您知道是否使用了静脉输液吗?我假设是的,因为您不想使用相同的密钥加密多个值,除非您每次都使用唯一的 IV。但假设加密文件的人不知道这一点,您可以使用 openssl 命令行来解密文件: openssl enc -aes-128-cbc -in 'file' -out 'file.ts' -K 'key'跨度>
  • @j-u-s-t-i-n 不知道,但有两个问题。1)这看起来像编码文件的语法。 2)我需要解密来合并文件。
  • 那不是编码而是解密。我不熟悉 ffmpeg 格式,但如果您只需要组合文件解密它们,创建一个字节数组并将解密的字节按顺序放置,即 file1 + file2 + file3,然后以您需要的编码对字节进行编码。如果您需要合并文件,我不会使用命令行并将输出文件复制/粘贴在一起,而是应该使用 openssl api c/c++ 或用于 .NET 的 bouncy castle 并在代码中处理解密/合并:wiki.openssl.org/index.php/…
  • 我有一个问题:是否可以在没有密钥的情况下解密 .ts 文件?我已经下载了一些东西,但几乎不可能得到密钥。

标签: encryption ffmpeg


【解决方案1】:

我对此代码有一个小问题:

var folder = "path_to_folder";
byte[] encryptionKey = File.ReadAllBytes(folder + "path_to_key.key");

var outputFile = "c:\\i_love_you_guys.ts";
using (FileStream outputFileStream = new FileStream(outputFile, FileMode.Create))
{
    var files = Directory.GetFiles(folder, "*.ts");
    for (int i = 0; i < files.Length; i++)
    {
        byte[] encryptionIV = new byte[16];
        using (FileStream inputFileStream = new FileStream(files[i], FileMode.Open))
        {
            using (var aes = new AesManaged { Key = encryptionKey, IV = encryptionIV, Mode = CipherMode.CBC })
            using (var encryptor = aes.CreateDecryptor())
            using (var cryptoStream = new CryptoStream(inputFileStream, encryptor, CryptoStreamMode.Read))
            {
                cryptoStream.CopyTo(outputFileStream);
            }
        }
    }
}

如何单独解密而不是单个文件输出?

【讨论】:

    【解决方案2】:

    我今天有几个空闲时间,玩弄了这个。长话短说 - base64 密钥是 AES 加密的。这种额外的加密是使用从设备数据动态生成的密钥完成的......这意味着即使我从您的设备中获得了整个数据文件夹,我也无法解密它。

    现在,当您拥有带有离线数据的根设备时,这是另一回事 - 您显然可以注入代码以在密钥被解密时拦截密钥,以便内容可以开始播放......这就是我得到它的方式。

    当您拥有正确的密钥时,*.ts 文件的解密和加入是微不足道的。 我建议您 use FFMPEG for this task,我留下来用于说明的 C# 代码仅在某些情况下(取决于文件的编码方式)运行良好:: p>

    var folder = "path_to_folder";
    byte[] encryptionKey = File.ReadAllBytes(folder + "path_to_key.key");
    
    var outputFile = "c:\\i_love_you_guys.ts";
    using (FileStream outputFileStream = new FileStream(outputFile, FileMode.Create))
    {
        var files = Directory.GetFiles(folder, "*.ts");
        for (int i = 0; i < files.Length; i++)
        {
            byte[] encryptionIV = new byte[16];
            using (FileStream inputFileStream = new FileStream(files[i], FileMode.Open))
            {
                using (var aes = new AesManaged { Key = encryptionKey, IV = encryptionIV, Mode = CipherMode.CBC })
                using (var encryptor = aes.CreateDecryptor())
                using (var cryptoStream = new CryptoStream(inputFileStream, encryptor, CryptoStreamMode.Read))
                {
                    cryptoStream.CopyTo(outputFileStream);
                }
            }
        }
    }
    

    所以,结果证明这是一场大乱斗。只要您有正确的my.key,@aergistal 在他的回答中所说的就是完全有效的。因此,专注于以纯格式获取密钥和解密将变得非常容易。

    【讨论】:

    • 如何单独获取 TS 文件而不是单个 TS 文件?
    • @Oli 您可以创建多个流并将它们写入单独的文件。 IE。在 for 循环中移动 FileStream outputFileStream 创建。
    【解决方案3】:

    最新版本的 ffmpeg 应该能够解密 AES-128 HLS 流。您不需要网络服务器。如果m3u8 URI/路径错误,您可以:

    • 创建目录
    • 将密钥复制到密钥文件,即my.key,并将其放在目录中。请注意,如果播放列表有多个键,则可以轮换键,将它们全部复制到不同的文件中。
    • 将所有.ts段复制到同一个目录
    • 复制并编辑 playlist.m3u8,并仅使用文件名作为键 URI 和段。
    • 要获取单个.ts 文件,请执行以下操作:

      ffmpeg -i playlist.m3u8 -c copy output.ts
      
    • 如果您只想要没有.ts 容器的音频流,您可以提取它。例如:假设您有一个使用AAC 编解码器运行的音频流:

      ffmpeg -i playlist.m3u8 -map 0:a -c copy output.aac
      

    这会将AAC 流提取到文件中,而无需重新编码。如果您想要的编解码器与源代码不同,则必须重新编码。

    如果由于某种原因您必须使用openssl 来解密片段,请记住,如果没有指定IV,则IV 等于片段的媒体序列,即。第一段有IV=0,第二段有IV=1,以此类推。解密后更新播放列表以指向解密的片段并删除EXT-X-KEY 行。如果你走这条路,你甚至不需要 ffmpeg 来获得单个 .ts 文件,因为 MPEG-TS 是直接可连接的,即。您可以在解密的片段上使用cat

    【讨论】:

    • 很好的深入回答。不幸的是,它不起作用。见上面的附录。我完全按照您的描述进行了操作,但遇到了无效数据错误。
    • 这是从设备上出来的文件,44 个字符/44 个字节。除非密钥是一些红鲱鱼,否则这是 android 应用程序用来解密这些文件以进行播放的密钥。
    • 试试echo MoOoNvcKlThWBm2T+VzYq9QKZLw7MFUqSyLYjiwquTQ= | base64 --decode &gt; out.key
    • 是的。环顾四周,我发现了两个有趣的事情:An AES 256-bit key can be expressed as a hexadecimal string with 64 characters. It will require 44 characters in base64. 所以也许这只是假装它是 128 位加密?此外,它似乎是用 base 64 编码的。
    • @JonathonWisnoski 明白了。似乎base64密钥以某种方式加密。我已经设法绕过保护来获得普通的 16 字节密钥。一旦我有了密钥,我就使用了我昨天编写的实用程序,它可以轻松地将加密的 .ts 文件转换为一个解密的 .ts。奇怪的是,这与始终为 0 的 IV 一起使用。现在我有 16 字节密钥,我将看看是否可以弄清楚 base64 44 字节密钥如何映射到普通的 16 字节密钥。如果我弄清楚了,我会尝试开源我的代码,以便其他人可以从我的努力中学习;)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-30
    • 1970-01-01
    • 1970-01-01
    • 2020-09-14
    • 2013-04-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多