修正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(); 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:…… //上次读取到的加密行,#EXT-X-KEY:……
string lastKeyLine = ""; string lastKeyLine = "";
@ -290,23 +297,37 @@ namespace N_m3u8DL_RE.Parser.Extractor
//解析KEY //解析KEY
else if (line.StartsWith(HLSTags.ext_x_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 iv = ParserUtil.GetAttribute(line, "IV");
var method = ParserUtil.GetAttribute(line, "METHOD"); var method = ParserUtil.GetAttribute(line, "METHOD");
var uri = ParserUtil.GetAttribute(line, "URI"); var uri = ParserUtil.GetAttribute(line, "URI");
var uri_last = ParserUtil.GetAttribute(lastKeyLine, "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相同不进行重复解析 //如果KEY URL相同不进行重复解析
if (uri != uri_last) 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; lastKeyLine = line;
} }
@ -321,7 +342,7 @@ namespace N_m3u8DL_RE.Parser.Extractor
{ {
segment.EncryptInfo.Method = currentEncryptInfo.Method; segment.EncryptInfo.Method = currentEncryptInfo.Method;
segment.EncryptInfo.Key = currentEncryptInfo.Key; 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; expectSegment = true;
segIndex++; segIndex++;
@ -417,13 +438,13 @@ namespace N_m3u8DL_RE.Parser.Extractor
return playlist; 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) 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 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(); var encryptInfo = new EncryptInfo();
@ -28,33 +28,14 @@ namespace N_m3u8DL_RE.Parser.Processor.HLS
{ {
encryptInfo.Key = Convert.FromBase64String(uriText.Substring(23)); encryptInfo.Key = Convert.FromBase64String(uriText.Substring(23));
} }
else else if (!string.IsNullOrEmpty(uriText))
{ {
var segUrl = PreProcessUrl(ParserUtil.CombineURL(parserConfig.BaseUrl, uriText), parserConfig); var segUrl = PreProcessUrl(ParserUtil.CombineURL(parserConfig.BaseUrl, uriText), parserConfig);
var bytes = HTTPUtil.GetBytesAsync(segUrl, parserConfig.Headers).Result; var bytes = HTTPUtil.GetBytesAsync(segUrl, parserConfig.Headers).Result;
encryptInfo.Key = bytes; encryptInfo.Key = bytes;
} }
//加密方式 return encryptInfo.Key;
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;
} }
/// <summary> /// <summary>

View File

@ -10,7 +10,7 @@ namespace N_m3u8DL_RE.Parser.Processor
{ {
public abstract class KeyProcessor public abstract class KeyProcessor
{ {
public abstract bool CanProcess(string method, string uriText, string ivText, ParserConfig parserConfig); public abstract bool CanProcess(string method, string uriText, ParserConfig parserConfig);
public abstract EncryptInfo Process(string method, string uriText, string ivText, int segIndex, 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 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"); 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![/]"); Logger.InfoMarkUp("[white on green]My Key Processor![/]");
return new DefaultHLSKeyProcessor().Process(method, uriText, ivText, segIndex, parserConfig); return new DefaultHLSKeyProcessor().Process(method, uriText, parserConfig);
} }
} }
} }