You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用ChaCha20等流密码加密视频并保持可播放与流式传输性?

问题根源

你直接加密了整个MP4容器文件,包括播放器识别格式必需的文件头(如ftyp、moov等MP4盒子),导致播放器/FFmpeg无法解析文件结构,自然无法处理。流密码加密应该仅作用于媒体帧数据,而非整个容器文件。

可行解决方案

方案一:用FFmpeg原生ChaCha20加密(推荐适配流媒体场景)

FFmpeg原生支持ChaCha20加密,可直接处理媒体流,且兼容流式传输与播放。

1. 加密命令(生成可传输的加密流)

将视频转码并加密媒体流,输出为适合流式传输的TS容器:

# 注意:key和nonce需转为十六进制字符串(Python中可通过key.hex()获取)
ffmpeg -i input.mp4 -c:v libx264 -c:a aac -encryption_scheme chacha20 -encryption_key 32字节密钥十六进制 -encryption_nonce 16字节Nonce十六进制 output.ts

2. 解密播放命令(接收端)

  • FFmpeg直接解密播放:
ffmpeg -i output.ts -decryption_key 32字节密钥十六进制 -decryption_nonce 16字节Nonce十六进制 -f sdl "解密播放"
  • VLC播放:在「媒体→打开网络串流→编辑选项」中添加参数:
--demux=ts --decryption-key=密钥十六进制:Nonce十六进制

方案二:改进Python代码,仅加密媒体数据(保留容器头)

若必须用Python处理,需解析MP4结构,仅加密存储媒体帧的mdat盒子内容,保留文件头让播放器识别格式。

依赖安装

pip install pymp4

改进后代码

from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
import os
from pymp4.parser import MP4

def encrypt_mp4_media_data(input_file, output_file, key, nonce):
    # 解析MP4文件结构
    with open(input_file, 'rb') as f:
        mp4 = MP4(f.read())
    
    # 定位媒体数据盒子(mdat)并加密内容
    for box in mp4:
        if box.type == b'mdat':
            cipher = Cipher(algorithms.ChaCha20(key, nonce), mode=None, backend=default_backend())
            encryptor = cipher.encryptor()
            box.data = encryptor.update(box.data) + encryptor.finalize()
            break
    
    # 重新写入加密后的MP4文件
    with open(output_file, 'wb') as f:
        f.write(mp4.write())

def decrypt_mp4_media_data(input_file, output_file, key, nonce):
    with open(input_file, 'rb') as f:
        mp4 = MP4(f.read())
    
    for box in mp4:
        if box.type == b'mdat':
            cipher = Cipher(algorithms.ChaCha20(key, nonce), mode=None, backend=default_backend())
            decryptor = cipher.decryptor()
            box.data = decryptor.update(box.data) + decryptor.finalize()
            break
    
    with open(output_file, 'wb') as f:
        f.write(mp4.write())

# 生成密钥与Nonce(注意:Nonce必须每次加密唯一,不可重复使用同一Nonce+密钥)
key = os.urandom(32)
nonce = os.urandom(16)

encrypt_mp4_media_data('input.mp4', 'encrypted_media.mp4', key, nonce)
decrypt_mp4_media_data('encrypted_media.mp4', 'decrypted_media.mp4', key, nonce)

注意事项

ChaCha20的Nonce必须每次加密使用唯一值,重复使用同一Nonce+密钥会导致严重安全漏洞。

内容的提问来源于stack exchange,提问作者Higashira

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 08:58:24