修正HLS密钥解析逻辑

This commit is contained in:
nilaoda 2022-07-06 15:48:03 +08:00
parent 17e3a0c4ab
commit eb0a1d12dd
4 changed files with 44 additions and 42 deletions

View File

@ -215,6 +215,13 @@ namespace N_m3u8DL_RE.Parser.Extractor
//当前的加密信息
EncryptInfo currentEncryptInfo = new();
if (ParserConfig.CustomeKey != null)
{
currentEncryptInfo.Method = ParserConfig.CustomMethod ?? EncryptMethod.AES_128;
currentEncryptInfo.Key = ParserConfig.CustomeKey;
if (ParserConfig.CustomeIV != null)
currentEncryptInfo.IV = ParserConfig.CustomeIV;
}
//上次读取到的加密行,#EXT-X-KEY:……
string lastKeyLine = "";
@ -290,23 +297,37 @@ namespace N_m3u8DL_RE.Parser.Extractor
//解析KEY
else if (line.StartsWith(HLSTags.ext_x_key))
{
//自定义KEY情况 不读取当前行的KEY信息 但是没自定义当前行有IV的话 就用
if (ParserConfig.CustomeKey != null && ParserConfig.CustomeIV == null && line.Contains("IV=0x"))
{
currentEncryptInfo.IV = HexUtil.HexToBytes(ParserUtil.GetAttribute(line, "IV"));
continue;
}
var iv = ParserUtil.GetAttribute(line, "IV");
var method = ParserUtil.GetAttribute(line, "METHOD");
var uri = ParserUtil.GetAttribute(line, "URI");
var uri_last = ParserUtil.GetAttribute(lastKeyLine, "URI");
//自定义KEY情况 判断是否需要读取IV
if (line.Contains("IV=0x") && ParserConfig.CustomeKey != null && ParserConfig.CustomeIV == null)
{
currentEncryptInfo.Method = ParserConfig.CustomMethod ?? EncryptMethod.AES_128;
currentEncryptInfo.Key = ParserConfig.CustomeKey;
currentEncryptInfo.IV = HexUtil.HexToBytes(iv);
}
//如果KEY URL相同不进行重复解析
if (uri != uri_last)
{
//解析key
currentEncryptInfo = ParseKey(method, uri, iv, segIndex);
//加密方式
if (Enum.TryParse(method.Replace("-", "_"), out EncryptMethod m))
{
currentEncryptInfo.Method = m;
}
else
{
currentEncryptInfo.Method = EncryptMethod.UNKNOWN;
}
//IV
if (!string.IsNullOrEmpty(iv))
{
currentEncryptInfo.IV = HexUtil.HexToBytes(iv);
}
//KEY
currentEncryptInfo.Key = ParseKey(method, uri);
}
lastKeyLine = line;
}
@ -321,7 +342,7 @@ namespace N_m3u8DL_RE.Parser.Extractor
{
segment.EncryptInfo.Method = currentEncryptInfo.Method;
segment.EncryptInfo.Key = currentEncryptInfo.Key;
segment.EncryptInfo.IV = currentEncryptInfo.IV;
segment.EncryptInfo.IV = currentEncryptInfo.IV ?? HexUtil.HexToBytes(Convert.ToString(segIndex, 16).PadLeft(32, '0'));
}
expectSegment = true;
segIndex++;
@ -417,13 +438,13 @@ namespace N_m3u8DL_RE.Parser.Extractor
return playlist;
}
private EncryptInfo ParseKey(string method, string uriText, string ivText, int segIndex)
private byte[] ParseKey(string method, string uriText)
{
foreach (var p in ParserConfig.HLSKeyProcessors)
{
if (p.CanProcess(method, uriText, ivText, ParserConfig))
if (p.CanProcess(method, uriText, ParserConfig))
{
return p.Process(method, uriText, ivText, segIndex, ParserConfig);
return p.Process(method, uriText, ParserConfig);
}
}

View File

@ -13,9 +13,9 @@ namespace N_m3u8DL_RE.Parser.Processor.HLS
{
public class DefaultHLSKeyProcessor : KeyProcessor
{
public override bool CanProcess(string method, string uriText, string ivText, ParserConfig paserConfig) => true;
public override bool CanProcess(string method, string uriText, ParserConfig paserConfig) => true;
public override EncryptInfo Process(string method, string uriText, string ivText, int segIndex, ParserConfig parserConfig)
public override byte[] Process(string method, string uriText, ParserConfig parserConfig)
{
var encryptInfo = new EncryptInfo();
@ -28,33 +28,14 @@ namespace N_m3u8DL_RE.Parser.Processor.HLS
{
encryptInfo.Key = Convert.FromBase64String(uriText.Substring(23));
}
else
else if (!string.IsNullOrEmpty(uriText))
{
var segUrl = PreProcessUrl(ParserUtil.CombineURL(parserConfig.BaseUrl, uriText), parserConfig);
var bytes = HTTPUtil.GetBytesAsync(segUrl, parserConfig.Headers).Result;
encryptInfo.Key = bytes;
}
//加密方式
if (Enum.TryParse(method.Replace("-", "_"), out EncryptMethod m))
{
encryptInfo.Method = m;
}
else
{
encryptInfo.Method = EncryptMethod.UNKNOWN;
}
//没有读取到IV自己生成
if (string.IsNullOrEmpty(ivText))
{
encryptInfo.IV = HexUtil.HexToBytes(Convert.ToString(segIndex, 16).PadLeft(32, '0'));
}
else
{
encryptInfo.IV = HexUtil.HexToBytes(ivText);
}
return encryptInfo;
return encryptInfo.Key;
}
/// <summary>

View File

@ -10,7 +10,7 @@ namespace N_m3u8DL_RE.Parser.Processor
{
public abstract class KeyProcessor
{
public abstract bool CanProcess(string method, string uriText, string ivText, ParserConfig parserConfig);
public abstract EncryptInfo Process(string method, string uriText, string ivText, int segIndex, ParserConfig parserConfig);
public abstract bool CanProcess(string method, string uriText, ParserConfig parserConfig);
public abstract byte[] Process(string method, string uriText, ParserConfig parserConfig);
}
}

View File

@ -13,15 +13,15 @@ namespace N_m3u8DL_RE.Processor
{
internal class DemoProcessor2 : KeyProcessor
{
public override bool CanProcess(string method, string uriText, string ivText, ParserConfig parserConfig)
public override bool CanProcess(string method, string uriText, ParserConfig parserConfig)
{
return parserConfig.Url.Contains("playertest.longtailvideo.com");
}
public override EncryptInfo Process(string method, string uriText, string ivText, int segIndex, ParserConfig parserConfig)
public override byte[] Process(string method, string uriText, ParserConfig parserConfig)
{
Logger.InfoMarkUp("[white on green]My Key Processor![/]");
return new DefaultHLSKeyProcessor().Process(method, uriText, ivText, segIndex, parserConfig);
return new DefaultHLSKeyProcessor().Process(method, uriText, parserConfig);
}
}
}