• ffmpeg 4.4 cenc-aes-ctr 加解密 MP4 工程性质分析


    目录

    一、cenc-aes-ctr 原理介绍  

    二、显式 cenc-aes-ctr 和隐式 cenc-aes-ctr

    三、加密工具---ffmpeg

    四、播放---ffplay

    五、总结


    ​​​​​​​一、cenc-aes-ctr 原理介绍  

    1. 加密算法:CENC-AES-CTR 使用 AES(Advanced Encryption Standard)算法进行加密。

    2. CTR 模式:CENC-AES-CTR 使用 CTR(Counter)模式进行加密。CTR 模式将明文分成固定大小的数据块,然后使用加密密钥和初始化向量(IV)生成密钥流,将密钥流与明文数据块进行异或操作,得到密文数据块。CTR 模式具有高度的并行性和随机性,可以有效保护数据的安全性。

    3. 样本级别加密:CENC-AES-CTR 对媒体文件进行样本级别的加密,即对媒体文件中的每个样本(视频帧、音频帧等)进行独立的加密处理。每个样本都使用不同的 IV 和加密索引,以确保每个样本的加密唯一性。

    4. 加密参数:CENC-AES-CTR 加密方案使用一组加密参数来确保正确的解密。这些参数包括加密密钥、密钥标识符(KID)、加密索引、初始化向量(IV)等。加密参数可以存储在加密文件的元数据中或通过其他方式进行传递。

    5. 解密过程:在解密时,解密器使用相同的加密参数来还原加密过程。解密器使用加密索引和 IV 生成相应的密钥流,并将密钥流与密文数据块进行异或操作,以还原明文数据。

    简单理解就是,

            将未加密的MP4文件进行加密时,加密工具会生成一个随机的16字节的初始化向量(IV),使用该IV以及你提供的KID进行加密操作,加密后的MP4问价内部除了本来原有的视频数据,还会多了一些加密信息,包括KID和IV。然后在接收端通过Key来进行解密

            注意:KID和IV都会随着密文一起传输,而非手动输入。IV手动输入的是其他的aes-ctr算法。但Key需要额外传输,不会随密文传输。也就是说,解密的时候仅需告知对方Key即可,IV会从文件中读取。

            另外,IV 通常为16字节的16进制数据,当然8字节也是可以的,如果是8字节的那么后面的8字节统一设置为0,下图就是生成的 8 字节IV的, cenc是算法名称,即你采用的什么算法。

    二、显式 cenc-aes-ctr 和隐式 cenc-aes-ctr

            cenc-aes-ctr 再细分的话还可以分为显式和隐式两种。

            显式cenc-aes-ctr会在加密的MP4文件中的【moov】字段下生成【senc】、【saio】、【saiz】三个字段,见下图。

    【senc】:是一个用于存储样本级别加密信息的 Box(箱)。它包含了加密样本的相关信息,如加密算法、密钥标识符(KID)、加密索引、初始化向量(IV)等。

    【saio】:用于指示加密样本的辅助信息(如清晰度信息、时序信息等)的位置偏移。它指示了 Sample Auxiliary Information Sizes Box(【saiz】)和 Sample Auxiliary Information Data Box(【saiz】)的位置偏移,以便在解密时正确解析和使用这些辅助信息。

    【saiz】:用于指示加密样本的辅助信息的大小。它存储了加密样本的辅助信息的字节大小,以便在解密时正确解析和使用这些辅助信息。【saiz】Box 在加密的 MP4 文件中出现在 Sample Table Box(stbl)中,并与【saio】Box 相关联。

            隐式的cenc-aes-ctr加密则不会载【moov】字段下生成,可能【moof】字段下,也可能都没显示,需要通过其他数据推断出IV。

    三、加密工具---ffmpeg

            目前研究下来,只有ffmpeg支持显式的CENC-AES-CTR加密算法,还没找到其他的工具。

            ffmpeg加密命令如下:

    ffmpeg -i test2.mp4  -vcodec copy -acodec copy -encryption_scheme cenc-aes-ctr -encryption_key c7e16c4403654b85847037383f0c2db3 -encryption_kid a7e61c373e219033c21091fa607bf3b8 encrypted_IV_test.mp4
    

    命令说明

    test2.mp4 为输入文件

    encrypted_IV_test.mp4 为输出文件

    -vcodec copy 和 -acodec copy :指定视频流和音频流的编码方式为原始流的拷贝,即不进行重新编码,保持与原始文件相同的编码格式。

    -encryption_scheme cenc-aes-ctr :设置加密方案为 CENC-AES-CTR,即采用 CTR 模式进行加密。

    -encryption_key c7e16c4403654b85847037383f0c2db3 指定加密所使用的密钥,即解密所使用的 key。这里的c7e16c4403654b85847037383f0c2db3 是一个示例密钥,您可以替换为您自己的密钥。

    -encryption_kid a7e61c373e219033c21091fa607bf3b8:指定加密所使用的密钥标识符(KID)。这里的 a7e61c373e219033c21091fa607bf3b8 是一个示例 KID,您可以替换为您自己的密钥标识符。

          上一篇文章提到的IV参数,对于该算法实际上是不生效的,即使设置了encryption_IV的值,实际上根据cenc-aes-ctr算法要求,也是会被忽略掉的。还是随机生成的。故此处iv可以不写。

         对于隐式的cenc-aes-ctr 加密工具,bento4。命令如下:

    1. mp4encrypt --method MPEG-CENC --key 1:c7e16c4403654b85847037383f0c2db3:random --property 1:KID:a7e61c373e219033c21091fa607bf3b8 fragmented.mp4 animal_test_decrypted_random_only_one_8.mp4

    命令说明:

    --method MPEG-CENC : 加密算法为 MPEG-CENC ,这里MPEG-CENC里面其实包含了很多种加密算法,其中之一就是cenc-aes-ctr,根据后面的参数来决定是哪一种算法

    --key 1:c7e16c4403654b85847037383f0c2db3:random : c7e16c4403654b85847037383f0c2db3就是ffmpeg里面的key。random 是必须的,含义是动态生成16字节的iv。如果这里不用random,用具体的值,则不属于cenc-aes-ctr了。

    --property 1:KID:a7e61c373e219033c21091fa607bf3b8 :对应ffmpeg的kid

    fragmented.mp4 输入文件

    animal_test_decrypted_random_only_one_8.mp4 输出文件

    上面的bento4就是隐式的cenc-aes-ctr命令

    四、播放---ffplay

           ffplay 命令如下

    ffplay animal_test_decrypted_not_random_only_one_8.mp4 -decryption_key c7e16c4403654b85847037383f0c2db3
    

    animal_test_decrypted_not_random_only_one_8.mp4 : 播放的文件

    -decryption_key c7e16c4403654b85847037383f0c2db3 : 解密用的key c7e16c4403654b85847037383f0c2db3

            注意:对与ffplay4.4版本,也就是ffmpeg 4.4版本,是不支持隐式 cenc-aes-ctr 解密的,也就是说,只有在加密文件中存在【senc】、【saio】、【saiz】三个字段时,才能播放,否则会播放错误,错误信息如下:

            但是对于 ffplay 6.0版本,则不会报错,会正常播放。

    对于4.4 无法播放的问题,原因是ffmpeg 在播放cenc-aes-ctr加密的视频时,回去寻找对应的s【senc】字段,然后读该字段内部的加密信息。而隐式的cenc-aes-ctr加密算法,是没有【senc】字段的,因此ffmpeg就认为是默认的iv解密方式,iv就是初始值0,与实际的iv是不匹配的。就解析失败了。

    而6.0则不是直接查找senc字段,所以就不会有这个问题。

    五、总结

            如果想用ffmpeg4.4版本来播放 cenc-aes-ctr 加密的MP4 资源,那只能使用ffmpeg进行加密,加密不需要必须4.4,6.0版本也可以。如果你用的加密工具加密后【moov】缺少【senc】字段,那就是隐式的,就必须6.0版本播放,4.4版本无法播放。

  • 相关阅读:
    【数据结构】八大经典排序(两万字大总结)
    Redis入门完整教程:客户端案例分析
    @AliasFor注解
    ORA-03113:通信通道的文件结尾-完美解决方案
    python 面试算法题
    SpringBoot使用配置文件若干方式
    软考高级系统架构设计师系列之:案例分析典型试题六
    [前端框架]-VUE(下篇)
    MALUNet:一种多关注,轻量级的皮肤病变分割UNet
    升讯威在线客服系统的并发高性能数据处理技术:PLINQ并行查询技术
  • 原文地址:https://blog.csdn.net/qq_36924305/article/details/134425622