Лучший подход к декодированию подписи шифрования 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.

Author: Alessandro Ornano, 2014-02-02

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

 20
Author: Akhilesh, 2014-11-11 20:18:27

Ваш старый 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 и мог бы немного помочь себе, но разговор об этом в проекте кода заводит вас в тупик.

 2
Author: Dr Gadgir, 2016-08-18 11:34:07

Я перевел на 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
 0
Author: Alessandro Ornano, 2017-09-03 10:09:51