Лучший подход к декодированию подписи шифрования Youtube с использованием PHP или JS
Youtube использует зашифрованную подпись для некоторых видео, когда use_cipher_signature = true
в словаре возвращается через
http://www.youtube.com/get_video_info?&video_id=Video_Id
Идентификатор примера: _JQH3G0cCtY
Зашифрованная подпись на самом деле является зашифрованной подписью, которую любой может отладить с помощью нескольких наборов рабочих подписей. Но Youtube продолжает менять алгоритм скремблирования. Я видел несколько загрузчиков видео с Youtube, которые работают бесперебойно, не будучи затронутыми через эту меняющуюся игру. Я думаю, что они проверяют проигрыватель и извлекают сценарий декодирования из файла проигрывателя, и, следовательно, это поддерживает их работу.
Мне нужна некоторая помощь в отношении реальной техники, которую следует использовать в этом случае. Я знаю о "youtube-dl" - программе на python для загрузки видео. Поскольку я плохо разбираюсь в python, я думаю, что они используют тот же подход.
Также здесь доступен файл JS пользовательского скрипта: http://userscripts.org/scripts/show/25105 , который является делаю то же самое.
Мы будем признательны за любую помощь в разумном подходе к расшифровке зашифрованного кода на PHP или JS.
3 answers
Структура URL-адресов и шифровальный код постоянно меняются на Youtube. В настоящее время наилучший подход к расшифровке подписи шифра объясняется ниже:
Зашифрованная подпись на Youtube - это просто "зашифрованная" подпись, которую вы должны изменить в соответствии с алгоритмом, присутствующим в файле проигрывателя (проигрыватель HTML5 или Flash-плеер).
Например, http://www.youtube.com/watch?v=UxxajLWwzqY
в настоящее время использует следующий файл проигрывателя HTML5: //s.ytimg.com/yts/jsbin/html5player-vfltdb6U3.js
В в этом файле вы можете легко найти код расшифровки подписи, выполнив поиск "sig". Здесь в этом случае алгоритм таков:
function bz(a) {
a = a.split("");
a = cz(a, 61);
a = cz(a, 5);
a = a.reverse();
a = a.slice(2);
a = cz(a, 69);
a = a.slice(2);
a = a.reverse();
return a.join("")
}
function cz(a, b) {
var c = a[0];
a[0] = a[b % a.length];
a[b] = c;
return a
};
Выше приведен код расшифровки.
Но имейте в виду, что он продолжает меняться, когда они меняют файл проигрывателя, поэтому вам нужно постоянно нажимать на используемый файл проигрывателя.
Также для загрузки видео с зашифрованной подписью вам необходимо позаботиться об отправке одних и тех же файлов cookie, используя один и тот же заголовок агента пользователя, отправляя запрос с одного и того же IP-адреса, и отправка запроса вскоре после извлечения. Все это требуется или требовалось в какой-то момент
Если вас интересует алгоритм расшифровки шифров, пожалуйста, посетите Cipherapi
Еще один классный API: API Tystream
Ваш старый s.ytimg.com/yts/jsbin/html5player-vfltdb6U3.js
теперь 404, и новый URL, я думаю, выглядит немного более похоже hxxps://s.ytimg.com/yts/jsbin/player-en_US-vfl_cdzrt/base.js
Если вы поищете в JavaScript, то найдете фрагмент кода, который выглядит примерно так
function(a,b,c)
{
a=new Mr(a);
a.set("alr","yes");a.set("keepalive","yes");a.set("ratebypass","yes");a.set("mime",(0,window.encodeURIComponent)(b.mimeType.split(";")[0]));c&&a.set("signature",xr(c));return a},Jt=function(a,b){var c=Yr(b,"id"),c=c.replace(":",";");..............
}
Функция xr
, которую вызывает приведенный выше код, выглядит следующим образом
xr=function(a)
{
a=a.split("");
wr.rF(a,54);
wr.fs(a,75);
wr.N0(a,1);
wr.rF(a,52);
wr.N0(a,3);
wr.fs(a,31);
wr.rF(a,16);
wr.fs(a,38);
return a.join("")
}
После этого я начинаю немного запутываться в javascript и мог бы немного помочь себе, но разговор об этом в проекте кода заводит вас в тупик.
Я перевел на Swift 3 ответ Ахилеша для пользователей iOS:
func decryptSignature(signature:String)->String {
return bz(signature)
}
func bz(_ a:String)->String {
var arrayA = Array(a.characters)
arrayA = cz(arrayA, 61)
arrayA = cz(arrayA, 5)
arrayA = arrayA.reversed()
arrayA = Array(arrayA[2..<arrayA.count])
arrayA = cz(arrayA, 69)
arrayA = Array(arrayA[2..<arrayA.count])
arrayA = arrayA.reversed()
return String(arrayA)
}
func cz(_ a:Array<Character>, _ b:Int)->Array<Character> {
var arrayA = a
let c = a[0]
arrayA[0] = a[b % a.count];
arrayA[b] = c
return arrayA
}
Но я думаю, что этого алгоритма недостаточно, он расшифровывает подпись, следуя определенному правилу. На самом деле, в соответствии с этим скриптом perl (выложенным в Youtube Джейми Завински) алгоритм меняется каждый раз, и скрипт собирает список правил и алгоритмов в течение нескольких дней!. Пока в шифрах используются только три команды, поэтому мы можем их представить компактно:
# - r = reverse the string;
# - sN = slice from character N to the end;
# - wN = swap 0th and Nth character.
Я думаю, что лучший способ - это реализовать что-то вроде:
func decryptChiper(_ commands:String, signature:String)->String {
var a = Array(signature.characters)
let cmdArray:[String]! = commands.components(separatedBy: " ")
for cmd in cmdArray {
var value:Int!
if cmd.characters.count>1 {
let secondChar = cmd.index(cmd.startIndex, offsetBy: 1)
value = Int(cmd.substring(from:secondChar))
}
switch cmd[cmd.startIndex] {
case "r": a = a.reversed()
case "s":
if let sliceFrom = value {
a = Array(a[sliceFrom..<a.count])
}
case "w":
if let swapValue = value {
a = swap(a,swapValue)
}
default:break
}
}
return String(a)
}
func swap(_ a:Array<Character>, _ b:Int)->Array<Character> {
var arrayA = a
let c = a[0]
arrayA[0] = a[b % a.count];
arrayA[b] = c
return arrayA
}
Использование:
Чтобы привести пример, следующий за этим Ахилеш ответ:
let signature = "D3D3434498D70C3080D9B084E48350F6519A9E9A71094.25F300BB180DDDD918EE0EBEDD174EE5D874EFEFF"
let decryptedSign = decryptChiper("w61 w5 r s2 w69 s2 r", signature: signature )
print(decryptedSign)
Выход:
33D3494498D70C3E80D9B084E48350F6519A9E9A71094.25F300BB180DDDDD18EE0EBEDD174EE5D874E