如何用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
相关产品推荐
相关产品推荐

