1 (2021.03.19 08:44:20 отредактировано smsbox3)

Тема: Защита сайтов от парсинга

Последнее время все больше сайтов переходят на защиту javascriptом от парсинга и это становится проблемой.
Для примера есть бесплатный хостиг, который представлен под разными названиями (похоже там просто арендуют уже готовые решения разные организации и предлагают совершенно идентичный бесплатный хостинг), но физически одни сервера, одно ПО, одна и защита.
Так вот например у меня есть такой запрос

http://smsbox.qlihost.ru/you/new/g2.php?v=CHdGju51-Rk

, в браузере видим тестовый ответ, но если попробует считать средствами php возвращает ненужный javascript, с которым надо что-то делать.

+ открыть спойлер
<html><body><script type="text/javascript" src="/aes.js" ></script><script>function toNumbers(d){var e=[];d.replace(/(..)/g,function(d){e.push(parseInt(d,16))});return e}function toHex(){for(var d=[],d=1==arguments.length&&arguments[0].constructor==Array?arguments[0]:arguments,e="",f=0;f<d.length;f++)e+=(16>d[f]?"0":"")+d[f].toString(16);return e.toLowerCase()}var a=toNumbers("f655ba9d09a112d4968c63579db590b4"),b=toNumbers("98344c2eee86c3994890592585b49f80"),c=toNumbers("7911eb502bb09dd5dc9a3a65f304bd95");document.cookie="__test="+toHex(slowAES.decrypt(c,2,a,b))+"; expires=Thu, 31-Dec-37 23:55:55 GMT; path=/"; location.href="http://smsbox.qlihost.ru/you/new/g2.php?v=CHdGju51-Rk&i=1";</script><noscript>This site requires Javascript to work, please enable Javascript in your browser or use a browser with Javascript support</noscript></body></html>

файлик aes.js скачать не проблема

http://smsbox.qlihost.ru/aes.js

Кстати этим можно проверять хостинг реальный тот самый бесплатный или это что-то другое.

Что я тут вижу? Устанавливается кук с именем

__test

  до 31-Dec-37 23:55:55  т.е. в нашем случае вечный.
цифры а,b,c неизменны (причем на разных сайтах этого хостинга они те же самые, и похоже не зависят от времени, вчера были те же)
Формула функции получения кука -  slowAES.decrypt(c,2,a,b) то же неизменна.
В браузере я вижу такое значение  __test=7b2145b094a3f1881cdc4d25d1072f10 При смене домена на другой бесплатный хостинг остается тот же самый кукис.
ту либо к ip привязка, либо вообще случайное число?
Если кому-то будет интересно поломать голову, вот ссылка того, что можно попробовать прочитать

http://smsbox.qlihost.ru/you/new/g2.php?v=CHdGju51-Rk

Вот, функция кодирования кукиса (AES - это «симметричный блочный шифр» для шифрования текстов одобрено правительством США для секретной информации до «секретной» - и с длиной ключа 192 или 256, вплоть до «совершенно секретно»)

+ открыть спойлер
/*
 * aes.js: implements AES - Advanced Encryption Standard
 * from the SlowAES project, http://code.google.com/p/slowaes/
 * 
 * Copyright (c) 2008     Josh Davis ( http://www.josh-davis.org ),
 *                        Mark Percival ( http://mpercival.com ),
 *
 * Ported from C code written by Laurent Haan ( http://www.progressive-coding.com )
 * 
 * Licensed under the Apache License, Version 2.0
 * http://www.apache.org/licenses/
 */

var slowAES = {
    /*
     * START AES SECTION
     */
    aes:{
        // structure of valid key sizes
        keySize:{
            SIZE_128:16,
            SIZE_192:24,
            SIZE_256:32
        },
        
        // Rijndael S-box
        sbox:[
        0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
        0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
        0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
        0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
        0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
        0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
        0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
        0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
        0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
        0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
        0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
        0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
        0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
        0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
        0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
        0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 ],
        
        // Rijndael Inverted S-box
        rsbox:
        [ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
        , 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
        , 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
        , 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
        , 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
        , 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
        , 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
        , 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
        , 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
        , 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
        , 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
        , 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
        , 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
        , 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
        , 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
        , 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d ],
        
        /* rotate the word eight bits to the left */
        rotate:function(word)
        {
            var c = word[0];
            for (var i = 0; i < 3; i++)
                word[i] = word[i+1];
            word[3] = c;
            
            return word;
        },
        
        // Rijndael Rcon
        Rcon:[
        0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
        0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
        0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
        0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d,
        0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab,
        0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d,
        0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25,
        0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01,
        0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d,
        0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa,
        0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a,
        0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02,
        0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
        0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
        0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
        0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
        0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f,
        0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5,
        0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33,
        0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb ],

        G2X: [
        0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16,
        0x18, 0x1a, 0x1c, 0x1e, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e,
        0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, 0x40, 0x42, 0x44, 0x46,
        0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
        0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76,
        0x78, 0x7a, 0x7c, 0x7e, 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e,
        0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, 0xa0, 0xa2, 0xa4, 0xa6,
        0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
        0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6,
        0xd8, 0xda, 0xdc, 0xde, 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee,
        0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, 0x1b, 0x19, 0x1f, 0x1d,
        0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05,
        0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d,
        0x23, 0x21, 0x27, 0x25, 0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55,
        0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45, 0x7b, 0x79, 0x7f, 0x7d,
        0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65,
        0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d,
        0x83, 0x81, 0x87, 0x85, 0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5,
        0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5, 0xdb, 0xd9, 0xdf, 0xdd,
        0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5,
        0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed,
        0xe3, 0xe1, 0xe7, 0xe5
        ],

        G3X: [
        0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d,
        0x14, 0x17, 0x12, 0x11, 0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39,
        0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21, 0x60, 0x63, 0x66, 0x65,
        0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71,
        0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d,
        0x44, 0x47, 0x42, 0x41, 0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9,
        0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1, 0xf0, 0xf3, 0xf6, 0xf5,
        0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1,
        0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd,
        0xb4, 0xb7, 0xb2, 0xb1, 0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99,
        0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81, 0x9b, 0x98, 0x9d, 0x9e,
        0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a,
        0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6,
        0xbf, 0xbc, 0xb9, 0xba, 0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2,
        0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea, 0xcb, 0xc8, 0xcd, 0xce,
        0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda,
        0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46,
        0x4f, 0x4c, 0x49, 0x4a, 0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62,
        0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a, 0x3b, 0x38, 0x3d, 0x3e,
        0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a,
        0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16,
        0x1f, 0x1c, 0x19, 0x1a
        ],

        G9X: [
        0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53,
        0x6c, 0x65, 0x7e, 0x77, 0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf,
        0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7, 0x3b, 0x32, 0x29, 0x20,
        0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
        0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94, 0xe3, 0xea, 0xf1, 0xf8,
        0xc7, 0xce, 0xd5, 0xdc, 0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49,
        0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01, 0xe6, 0xef, 0xf4, 0xfd,
        0xc2, 0xcb, 0xd0, 0xd9, 0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91,
        0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72, 0x05, 0x0c, 0x17, 0x1e,
        0x21, 0x28, 0x33, 0x3a, 0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2,
        0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa, 0xec, 0xe5, 0xfe, 0xf7,
        0xc8, 0xc1, 0xda, 0xd3, 0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b,
        0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43, 0x34, 0x3d, 0x26, 0x2f,
        0x10, 0x19, 0x02, 0x0b, 0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8,
        0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0, 0x47, 0x4e, 0x55, 0x5c,
        0x63, 0x6a, 0x71, 0x78, 0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30,
        0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9,
        0xf6, 0xff, 0xe4, 0xed, 0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35,
        0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d, 0xa1, 0xa8, 0xb3, 0xba,
        0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6,
        0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62,
        0x5d, 0x54, 0x4f, 0x46
        ],

        GBX: [
        0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45,
        0x74, 0x7f, 0x62, 0x69, 0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81,
        0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9, 0x7b, 0x70, 0x6d, 0x66,
        0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12,
        0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa, 0x93, 0x98, 0x85, 0x8e,
        0xbf, 0xb4, 0xa9, 0xa2, 0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7,
        0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f, 0x46, 0x4d, 0x50, 0x5b,
        0x6a, 0x61, 0x7c, 0x77, 0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f,
        0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc, 0xd5, 0xde, 0xc3, 0xc8,
        0xf9, 0xf2, 0xef, 0xe4, 0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c,
        0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54, 0xf7, 0xfc, 0xe1, 0xea,
        0xdb, 0xd0, 0xcd, 0xc6, 0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e,
        0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76, 0x1f, 0x14, 0x09, 0x02,
        0x33, 0x38, 0x25, 0x2e, 0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd,
        0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5, 0x3c, 0x37, 0x2a, 0x21,
        0x10, 0x1b, 0x06, 0x0d, 0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55,
        0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44,
        0x75, 0x7e, 0x63, 0x68, 0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80,
        0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8, 0x7a, 0x71, 0x6c, 0x67,
        0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13,
        0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f,
        0xbe, 0xb5, 0xa8, 0xa3
        ],

        GDX: [
        0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f,
        0x5c, 0x51, 0x46, 0x4b, 0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3,
        0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b, 0xbb, 0xb6, 0xa1, 0xac,
        0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0,
        0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48, 0x03, 0x0e, 0x19, 0x14,
        0x37, 0x3a, 0x2d, 0x20, 0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e,
        0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26, 0xbd, 0xb0, 0xa7, 0xaa,
        0x89, 0x84, 0x93, 0x9e, 0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6,
        0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5, 0xbe, 0xb3, 0xa4, 0xa9,
        0x8a, 0x87, 0x90, 0x9d, 0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25,
        0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d, 0xda, 0xd7, 0xc0, 0xcd,
        0xee, 0xe3, 0xf4, 0xf9, 0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91,
        0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29, 0x62, 0x6f, 0x78, 0x75,
        0x56, 0x5b, 0x4c, 0x41, 0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42,
        0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a, 0xb1, 0xbc, 0xab, 0xa6,
        0x85, 0x88, 0x9f, 0x92, 0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa,
        0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8,
        0xeb, 0xe6, 0xf1, 0xfc, 0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44,
        0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c, 0x0c, 0x01, 0x16, 0x1b,
        0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47,
        0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3,
        0x80, 0x8d, 0x9a, 0x97
        ],

        GEX: [
        0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62,
        0x48, 0x46, 0x54, 0x5a, 0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca,
        0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba, 0xdb, 0xd5, 0xc7, 0xc9,
        0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81,
        0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11, 0x4b, 0x45, 0x57, 0x59,
        0x73, 0x7d, 0x6f, 0x61, 0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87,
        0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7, 0x4d, 0x43, 0x51, 0x5f,
        0x75, 0x7b, 0x69, 0x67, 0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17,
        0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c, 0x06, 0x08, 0x1a, 0x14,
        0x3e, 0x30, 0x22, 0x2c, 0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc,
        0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc, 0x41, 0x4f, 0x5d, 0x53,
        0x79, 0x77, 0x65, 0x6b, 0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b,
        0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b, 0xd1, 0xdf, 0xcd, 0xc3,
        0xe9, 0xe7, 0xf5, 0xfb, 0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0,
        0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0, 0x7a, 0x74, 0x66, 0x68,
        0x42, 0x4c, 0x5e, 0x50, 0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20,
        0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e,
        0xa4, 0xaa, 0xb8, 0xb6, 0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26,
        0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56, 0x37, 0x39, 0x2b, 0x25,
        0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d,
        0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5,
        0x9f, 0x91, 0x83, 0x8d
        ],
        
        // Key Schedule Core
        core:function(word,iteration)
        {
            /* rotate the 32-bit word 8 bits to the left */
            word = this.rotate(word);
            /* apply S-Box substitution on all 4 parts of the 32-bit word */
            for (var i = 0; i < 4; ++i)
                word[i] = this.sbox[word[i]];
            /* XOR the output of the rcon operation with i to the first part (leftmost) only */
            word[0] = word[0]^this.Rcon[iteration];
            return word;
        },
        
        /* Rijndael's key expansion
         * expands an 128,192,256 key into an 176,208,240 bytes key
         *
         * expandedKey is a pointer to an char array of large enough size
         * key is a pointer to a non-expanded key
         */
        expandKey:function(key,size)
        {
            var expandedKeySize = (16*(this.numberOfRounds(size)+1));
            
            /* current expanded keySize, in bytes */
            var currentSize = 0;
            var rconIteration = 1;
            var t = [];   // temporary 4-byte variable
            
            var expandedKey = [];
            for(var i = 0;i < expandedKeySize;i++)
                expandedKey[i] = 0;
        
            /* set the 16,24,32 bytes of the expanded key to the input key */
            for (var j = 0; j < size; j++)
                expandedKey[j] = key[j];
            currentSize += size;
        
            while (currentSize < expandedKeySize)
            {
                /* assign the previous 4 bytes to the temporary value t */
                for (var k = 0; k < 4; k++)
                    t[k] = expandedKey[(currentSize - 4) + k];
        
                /* every 16,24,32 bytes we apply the core schedule to t
                 * and increment rconIteration afterwards
                 */
                if(currentSize % size == 0)
                    t = this.core(t, rconIteration++);
        
                /* For 256-bit keys, we add an extra sbox to the calculation */
                if(size == this.keySize.SIZE_256 && ((currentSize % size) == 16))
                    for(var l = 0; l < 4; l++)
                        t[l] = this.sbox[t[l]];
        
                /* We XOR t with the four-byte block 16,24,32 bytes before the new expanded key.
                 * This becomes the next four bytes in the expanded key.
                 */
                for(var m = 0; m < 4; m++) {
                    expandedKey[currentSize] = expandedKey[currentSize - size] ^ t[m];
                    currentSize++;
                }
            }
            return expandedKey;
        },
        
        // Adds (XORs) the round key to the state
        addRoundKey:function(state,roundKey)
        {
            for (var i = 0; i < 16; i++)
                state[i] ^= roundKey[i];
            return state;
        },
        
        // Creates a round key from the given expanded key and the
        // position within the expanded key.
        createRoundKey:function(expandedKey,roundKeyPointer)
        {
            var roundKey = [];
            for (var i = 0; i < 4; i++)
                for (var j = 0; j < 4; j++)
                    roundKey[j*4+i] = expandedKey[roundKeyPointer + i*4 + j];
            return roundKey;
        },
        
        /* substitute all the values from the state with the value in the SBox
         * using the state value as index for the SBox
         */
        subBytes:function(state,isInv)
        {
            for (var i = 0; i < 16; i++)
                state[i] = isInv?this.rsbox[state[i]]:this.sbox[state[i]];
            return state;
        },
        
        /* iterate over the 4 rows and call shiftRow() with that row */
        shiftRows:function(state,isInv)
        {
            for (var i = 0; i < 4; i++)
                state = this.shiftRow(state,i*4, i,isInv);
            return state;
        },
        
        /* each iteration shifts the row to the left by 1 */
        shiftRow:function(state,statePointer,nbr,isInv)
        {
            for (var i = 0; i < nbr; i++)
            {
                if(isInv)
                {
                    var tmp = state[statePointer + 3];
                    for (var j = 3; j > 0; j--)
                        state[statePointer + j] = state[statePointer + j-1];
                    state[statePointer] = tmp;
                }
                else
                {
                    var tmp = state[statePointer];
                    for (var j = 0; j < 3; j++)
                        state[statePointer + j] = state[statePointer + j+1];
                    state[statePointer + 3] = tmp;
                }
            }
            return state;
        },

        // galois multiplication of 8 bit characters a and b
        galois_multiplication:function(a,b)
        {
            var p = 0;
            for(var counter = 0; counter < 8; counter++)
            {
                if((b & 1) == 1)
                    p ^= a;
                if(p > 0x100) p ^= 0x100;
                var hi_bit_set = (a & 0x80); //keep p 8 bit
                a <<= 1;
                if(a > 0x100) a ^= 0x100; //keep a 8 bit
                if(hi_bit_set == 0x80)
                    a ^= 0x1b;
                if(a > 0x100) a ^= 0x100; //keep a 8 bit
                b >>= 1;
                if(b > 0x100) b ^= 0x100; //keep b 8 bit
            }
            return p;
        },
        
        // galois multipication of the 4x4 matrix
        mixColumns:function(state,isInv)
        {
            var column = [];
            /* iterate over the 4 columns */
            for (var i = 0; i < 4; i++)
            {
                /* construct one column by iterating over the 4 rows */
                for (var j = 0; j < 4; j++)
                    column[j] = state[(j*4)+i];
                /* apply the mixColumn on one column */
                column = this.mixColumn(column,isInv);
                /* put the values back into the state */
                for (var k = 0; k < 4; k++)
                    state[(k*4)+i] = column[k];
            }
            return state;
        },

        // galois multipication of 1 column of the 4x4 matrix
        mixColumn:function(column,isInv)
        {
            var mult = [];    
            if(isInv)
                mult = [14,9,13,11];
            else
                mult = [2,1,1,3];
            var cpy = [];
            for(var i = 0; i < 4; i++)
                cpy[i] = column[i];
            
            column[0] =     this.galois_multiplication(cpy[0],mult[0]) ^
                    this.galois_multiplication(cpy[3],mult[1]) ^
                    this.galois_multiplication(cpy[2],mult[2]) ^
                    this.galois_multiplication(cpy[1],mult[3]);
            column[1] =     this.galois_multiplication(cpy[1],mult[0]) ^
                    this.galois_multiplication(cpy[0],mult[1]) ^
                    this.galois_multiplication(cpy[3],mult[2]) ^
                    this.galois_multiplication(cpy[2],mult[3]);
            column[2] =     this.galois_multiplication(cpy[2],mult[0]) ^
                    this.galois_multiplication(cpy[1],mult[1]) ^
                    this.galois_multiplication(cpy[0],mult[2]) ^
                    this.galois_multiplication(cpy[3],mult[3]);
            column[3] =     this.galois_multiplication(cpy[3],mult[0]) ^
                    this.galois_multiplication(cpy[2],mult[1]) ^
                    this.galois_multiplication(cpy[1],mult[2]) ^
                    this.galois_multiplication(cpy[0],mult[3]);
            return column;
        },
        
        // applies the 4 operations of the forward round in sequence
        round:function(state, roundKey)
        {
            state = this.subBytes(state,false);
            state = this.shiftRows(state,false);
            state = this.mixColumns(state,false);
            state = this.addRoundKey(state, roundKey);
            return state;
        },
        
        // applies the 4 operations of the inverse round in sequence
        invRound:function(state,roundKey)
        {
            state = this.shiftRows(state,true);
            state = this.subBytes(state,true);
            state = this.addRoundKey(state, roundKey);
            state = this.mixColumns(state,true);
            return state;
        },
        
        /*
         * Perform the initial operations, the standard round, and the final operations
         * of the forward aes, creating a round key for each round
         */
        main:function(state,expandedKey,nbrRounds)
        {
            state = this.addRoundKey(state, this.createRoundKey(expandedKey,0));
            for (var i = 1; i < nbrRounds; i++)
                state = this.round(state, this.createRoundKey(expandedKey,16*i));
            state = this.subBytes(state,false);
            state = this.shiftRows(state,false);
            state = this.addRoundKey(state, this.createRoundKey(expandedKey,16*nbrRounds));
            return state;
        },
        
        /*
         * Perform the initial operations, the standard round, and the final operations
         * of the inverse aes, creating a round key for each round
         */
        invMain:function(state, expandedKey, nbrRounds)
        {
            state = this.addRoundKey(state, this.createRoundKey(expandedKey,16*nbrRounds));
            for (var i = nbrRounds-1; i > 0; i--)
                state = this.invRound(state, this.createRoundKey(expandedKey,16*i));
            state = this.shiftRows(state,true);
            state = this.subBytes(state,true);
            state = this.addRoundKey(state, this.createRoundKey(expandedKey,0));
            return state;
        },

        numberOfRounds:function(size)
        {
            var nbrRounds;
            switch (size) /* set the number of rounds */
            {
                case this.keySize.SIZE_128:
                    nbrRounds = 10;
                    break;
                case this.keySize.SIZE_192:
                    nbrRounds = 12;
                    break;
                case this.keySize.SIZE_256:
                    nbrRounds = 14;
                    break;
                default:
                    return null;
                    break;
            }
            return nbrRounds;
        },
        
        // encrypts a 128 bit input block against the given key of size specified
        encrypt:function(input,key,size)
        {
            var output = [];
            var block = []; /* the 128 bit block to encode */
            var nbrRounds = this.numberOfRounds(size);
            /* Set the block values, for the block:
             * a0,0 a0,1 a0,2 a0,3
             * a1,0 a1,1 a1,2 a1,3
             * a2,0 a2,1 a2,2 a2,3
             * a3,0 a3,1 a3,2 a3,3
             * the mapping order is a0,0 a1,0 a2,0 a3,0 a0,1 a1,1 ... a2,3 a3,3
             */
            for (var i = 0; i < 4; i++) /* iterate over the columns */
                for (var j = 0; j < 4; j++) /* iterate over the rows */
                    block[(i+(j*4))] = input[(i*4)+j];
        
            /* expand the key into an 176, 208, 240 bytes key */
            var expandedKey = this.expandKey(key, size); /* the expanded key */
            /* encrypt the block using the expandedKey */
            block = this.main(block, expandedKey, nbrRounds);
            for (var k = 0; k < 4; k++) /* unmap the block again into the output */
                for (var l = 0; l < 4; l++) /* iterate over the rows */
                    output[(k*4)+l] = block[(k+(l*4))];
            return output;
        },
        
        // decrypts a 128 bit input block against the given key of size specified
        decrypt:function(input, key, size)
        {
            var output = [];
            var block = []; /* the 128 bit block to decode */
            var nbrRounds = this.numberOfRounds(size);
            /* Set the block values, for the block:
             * a0,0 a0,1 a0,2 a0,3
             * a1,0 a1,1 a1,2 a1,3
             * a2,0 a2,1 a2,2 a2,3
             * a3,0 a3,1 a3,2 a3,3
             * the mapping order is a0,0 a1,0 a2,0 a3,0 a0,1 a1,1 ... a2,3 a3,3
             */
            for (var i = 0; i < 4; i++) /* iterate over the columns */
                for (var j = 0; j < 4; j++) /* iterate over the rows */
                    block[(i+(j*4))] = input[(i*4)+j];
            /* expand the key into an 176, 208, 240 bytes key */
            var expandedKey = this.expandKey(key, size);
            /* decrypt the block using the expandedKey */
            block = this.invMain(block, expandedKey, nbrRounds);
            for (var k = 0; k < 4; k++)/* unmap the block again into the output */
                for (var l = 0; l < 4; l++)/* iterate over the rows */
                    output[(k*4)+l] = block[(k+(l*4))];
            return output;
        }
    },
    /*
     * END AES SECTION
     */
     
    /*
     * START MODE OF OPERATION SECTION
     */
    //structure of supported modes of operation
    modeOfOperation:{
        OFB:0,
        CFB:1,
        CBC:2
    },
    
    // get a 16 byte block (aes operates on 128bits)
    getBlock: function(bytesIn,start,end,mode)
    {
        if(end - start > 16)
            end = start + 16;
        
        return bytesIn.slice(start, end);
    },
    
    /*
     * Mode of Operation Encryption
     * bytesIn - Input String as array of bytes
     * mode - mode of type modeOfOperation
     * key - a number array of length 'size'
     * size - the bit length of the key
     * iv - the 128 bit number array Initialization Vector
     */
    encrypt: function (bytesIn, mode, key, iv)
    {
        var size = key.length;
        if(iv.length%16)
        {
            throw 'iv length must be 128 bits.';
        }
        // the AES input/output
        var byteArray = [];
        var input = [];
        var output = [];
        var ciphertext = [];
        var cipherOut = [];
        // char firstRound
        var firstRound = true;
        if (mode == this.modeOfOperation.CBC)
            this.padBytesIn(bytesIn);
        if (bytesIn !== null)
        {
            for (var j = 0;j < Math.ceil(bytesIn.length/16); j++)
            {
                var start = j*16;
                var end = j*16+16;
                if(j*16+16 > bytesIn.length)
                    end = bytesIn.length;
                byteArray = this.getBlock(bytesIn,start,end,mode);
                if (mode == this.modeOfOperation.CFB)
                {
                    if (firstRound)
                    {
                        output = this.aes.encrypt(iv, key, size);
                        firstRound = false;
                    }
                    else
                        output = this.aes.encrypt(input, key, size);
                    for (var i = 0; i < 16; i++)
                        ciphertext[i] = byteArray[i] ^ output[i];
                    for(var k = 0;k < end-start;k++)
                        cipherOut.push(ciphertext[k]);
                    input = ciphertext;
                }
                else if (mode == this.modeOfOperation.OFB)
                {
                    if (firstRound)
                    {
                        output = this.aes.encrypt(iv, key, size);
                        firstRound = false;
                    }
                    else
                        output = this.aes.encrypt(input, key, size);
                    for (var i = 0; i < 16; i++)
                        ciphertext[i] = byteArray[i] ^ output[i];
                    for(var k = 0;k < end-start;k++)
                        cipherOut.push(ciphertext[k]);
                    input = output;
                }
                else if (mode == this.modeOfOperation.CBC)
                {
                    for (var i = 0; i < 16; i++)
                        input[i] = byteArray[i] ^ ((firstRound) ? iv[i] : ciphertext[i]);
                    firstRound = false;
                    ciphertext = this.aes.encrypt(input, key, size);
                    // always 16 bytes because of the padding for CBC
                    for(var k = 0;k < 16;k++)
                        cipherOut.push(ciphertext[k]);
                }
            }
        }
        return cipherOut;
    },
    
    /*
     * Mode of Operation Decryption
     * cipherIn - Encrypted String as array of bytes
     * originalsize - The unencrypted string length - required for CBC
     * mode - mode of type modeOfOperation
     * key - a number array of length 'size'
     * size - the bit length of the key
     * iv - the 128 bit number array Initialization Vector
     */
    decrypt:function(cipherIn,mode,key,iv)
    {
        var size = key.length;
        if(iv.length%16)
        {
            throw 'iv length must be 128 bits.';
        }
        // the AES input/output
        var ciphertext = [];
        var input = [];
        var output = [];
        var byteArray = [];
        var bytesOut = [];
        // char firstRound
        var firstRound = true;
        if (cipherIn !== null)
        {
            for (var j = 0;j < Math.ceil(cipherIn.length/16); j++)
            {
                var start = j*16;
                var end = j*16+16;
                if(j*16+16 > cipherIn.length)
                    end = cipherIn.length;
                ciphertext = this.getBlock(cipherIn,start,end,mode);
                if (mode == this.modeOfOperation.CFB)
                {
                    if (firstRound)
                    {
                        output = this.aes.encrypt(iv, key, size);
                        firstRound = false;
                    }
                    else
                        output = this.aes.encrypt(input, key, size);
                    for (i = 0; i < 16; i++)
                        byteArray[i] = output[i] ^ ciphertext[i];
                    for(var k = 0;k < end-start;k++)
                        bytesOut.push(byteArray[k]);
                    input = ciphertext;
                }
                else if (mode == this.modeOfOperation.OFB)
                {
                    if (firstRound)
                    {
                        output = this.aes.encrypt(iv, key, size);
                        firstRound = false;
                    }
                    else
                        output = this.aes.encrypt(input, key, size);
                    for (i = 0; i < 16; i++)
                        byteArray[i] = output[i] ^ ciphertext[i];
                    for(var k = 0;k < end-start;k++)
                        bytesOut.push(byteArray[k]);
                    input = output;
                }
                else if(mode == this.modeOfOperation.CBC)
                {
                    output = this.aes.decrypt(ciphertext, key, size);
                    for (i = 0; i < 16; i++)
                        byteArray[i] = ((firstRound) ? iv[i] : input[i]) ^ output[i];
                    firstRound = false;
                    for(var k = 0;k < end-start;k++)
                        bytesOut.push(byteArray[k]);
                    input = ciphertext;
                }
            }
            if(mode == this.modeOfOperation.CBC)
                this.unpadBytesOut(bytesOut);
        }
        return bytesOut;
    },
    padBytesIn: function(data) {
        var len = data.length;
        var padByte = 16 - (len % 16);
        for (var i = 0; i < padByte; i++) {
            data.push(padByte);
        }
    },
    unpadBytesOut: function(data) {
        var padCount = 0;
        var padByte = -1;
        var blockSize = 16;
        if (data.length > 16) {
        for (var i = data.length - 1; i >= data.length-1 - blockSize; i--) {
            if (data[i] <= blockSize) {
                if (padByte == -1)
                    padByte = data[i];
                if (data[i] != padByte) {
                    padCount = 0;
                    break;
                }
                padCount++;
            } else
                break;
            if (padCount == padByte)
                break;
        }
        if (padCount > 0)
            data.splice(data.length - padCount, padCount);
        }
    }
    /*
     * END MODE OF OPERATION SECTION
     */
};

2 (2021.03.19 13:18:07 отредактировано smsbox3)

Re: Защита сайтов от парсинга

Нашел по этому вопрос заметку

https://qna.habr.com/q/627776

Там С имеет другое значение

c = toNumbers("a37dcb8d65f1b5d98d196ec3731b3e74");

, а и b те же, что у меня.
Еще в одном месте посмотрел

var a = toNumbers("f655ba9d09a112d4968c63579db590b4"),
                b = toNumbers("98344c2eee86c3994890592585b49f80"),
                c = toNumbers("568c5a3227852f5cc113bd8ba3b64dc3");

а и b теже, с другой.

проверил запросом с другого сервера - точно c=toNumbers("351626b6f88c85079e9282d14037064d"
Выходит это привязка к ip

3

Re: Защита сайтов от парсинга

Оказывается эта функция давно реализована на php

+ открыть спойлер
<?php
/*
 * aes.php: implements AES - Advanced Encryption Standard
 * from the SlowAES project, http://code.google.com/p/slowaes/
 * 
 * Copyright (c) 2008     Josh Davis ( http://www.josh-davis.org ),
 *                        Mark Percival ( http://mpercival.com ),
 *
 * Ported from C code written by Laurent Haan ( http://www.progressive-coding.com )
 * 
 * Ported from JavaScript to PHP by ALeX Kazik
 * 
 * Licensed under the Apache License, Version 2.0
 * http://www.apache.org/licenses/
 */

class AES {
    /*
     * START AES SECTION
     */
    
    const keySize_128 = 16;
    const keySize_192 = 24;
    const keySize_256 = 32;
        
        // Rijndael S-box
    private static $sbox = array(
        0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
        0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
        0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
        0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
        0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
        0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
        0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
        0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
        0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
        0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
        0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
        0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
        0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
        0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
        0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
        0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
    );
        
        // Rijndael Inverted S-box
    private static $rsbox = array(
          0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
        , 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
        , 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
        , 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
        , 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
        , 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
        , 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
        , 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
        , 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
        , 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
        , 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
        , 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
        , 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
        , 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
        , 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
        , 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
    );
        
        /* rotate the word eight bits to the left */
    private static function rotate($word){
        $c = $word[0];
        for ($i = 0; $i < 3; $i++)
            $word[$i] = $word[$i+1];
        $word[3] = $c;
        
        return $word;
    }
        
        // Rijndael Rcon
    private static $Rcon = array(
        0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
        0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
        0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
        0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d,
        0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab,
        0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d,
        0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25,
        0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01,
        0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d,
        0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa,
        0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a,
        0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02,
        0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
        0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
        0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
        0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
        0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f,
        0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5,
        0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33,
        0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb
    );

    private static $G2X = array(
        0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16,
        0x18, 0x1a, 0x1c, 0x1e, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e,
        0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, 0x40, 0x42, 0x44, 0x46,
        0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
        0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76,
        0x78, 0x7a, 0x7c, 0x7e, 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e,
        0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, 0xa0, 0xa2, 0xa4, 0xa6,
        0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
        0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6,
        0xd8, 0xda, 0xdc, 0xde, 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee,
        0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, 0x1b, 0x19, 0x1f, 0x1d,
        0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05,
        0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d,
        0x23, 0x21, 0x27, 0x25, 0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55,
        0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45, 0x7b, 0x79, 0x7f, 0x7d,
        0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65,
        0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d,
        0x83, 0x81, 0x87, 0x85, 0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5,
        0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5, 0xdb, 0xd9, 0xdf, 0xdd,
        0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5,
        0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed,
        0xe3, 0xe1, 0xe7, 0xe5
    );

    private static $G3X = array(
        0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d,
        0x14, 0x17, 0x12, 0x11, 0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39,
        0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21, 0x60, 0x63, 0x66, 0x65,
        0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71,
        0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d,
        0x44, 0x47, 0x42, 0x41, 0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9,
        0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1, 0xf0, 0xf3, 0xf6, 0xf5,
        0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1,
        0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd,
        0xb4, 0xb7, 0xb2, 0xb1, 0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99,
        0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81, 0x9b, 0x98, 0x9d, 0x9e,
        0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a,
        0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6,
        0xbf, 0xbc, 0xb9, 0xba, 0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2,
        0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea, 0xcb, 0xc8, 0xcd, 0xce,
        0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda,
        0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46,
        0x4f, 0x4c, 0x49, 0x4a, 0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62,
        0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a, 0x3b, 0x38, 0x3d, 0x3e,
        0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a,
        0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16,
        0x1f, 0x1c, 0x19, 0x1a
    );

    private static $G9X = array(
        0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53,
        0x6c, 0x65, 0x7e, 0x77, 0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf,
        0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7, 0x3b, 0x32, 0x29, 0x20,
        0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
        0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94, 0xe3, 0xea, 0xf1, 0xf8,
        0xc7, 0xce, 0xd5, 0xdc, 0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49,
        0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01, 0xe6, 0xef, 0xf4, 0xfd,
        0xc2, 0xcb, 0xd0, 0xd9, 0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91,
        0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72, 0x05, 0x0c, 0x17, 0x1e,
        0x21, 0x28, 0x33, 0x3a, 0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2,
        0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa, 0xec, 0xe5, 0xfe, 0xf7,
        0xc8, 0xc1, 0xda, 0xd3, 0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b,
        0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43, 0x34, 0x3d, 0x26, 0x2f,
        0x10, 0x19, 0x02, 0x0b, 0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8,
        0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0, 0x47, 0x4e, 0x55, 0x5c,
        0x63, 0x6a, 0x71, 0x78, 0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30,
        0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9,
        0xf6, 0xff, 0xe4, 0xed, 0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35,
        0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d, 0xa1, 0xa8, 0xb3, 0xba,
        0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6,
        0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62,
        0x5d, 0x54, 0x4f, 0x46
    );

    private static $GBX = array(
        0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45,
        0x74, 0x7f, 0x62, 0x69, 0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81,
        0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9, 0x7b, 0x70, 0x6d, 0x66,
        0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12,
        0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa, 0x93, 0x98, 0x85, 0x8e,
        0xbf, 0xb4, 0xa9, 0xa2, 0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7,
        0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f, 0x46, 0x4d, 0x50, 0x5b,
        0x6a, 0x61, 0x7c, 0x77, 0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f,
        0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc, 0xd5, 0xde, 0xc3, 0xc8,
        0xf9, 0xf2, 0xef, 0xe4, 0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c,
        0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54, 0xf7, 0xfc, 0xe1, 0xea,
        0xdb, 0xd0, 0xcd, 0xc6, 0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e,
        0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76, 0x1f, 0x14, 0x09, 0x02,
        0x33, 0x38, 0x25, 0x2e, 0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd,
        0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5, 0x3c, 0x37, 0x2a, 0x21,
        0x10, 0x1b, 0x06, 0x0d, 0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55,
        0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44,
        0x75, 0x7e, 0x63, 0x68, 0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80,
        0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8, 0x7a, 0x71, 0x6c, 0x67,
        0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13,
        0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f,
        0xbe, 0xb5, 0xa8, 0xa3
    );

    private static $GDX = array(
        0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f,
        0x5c, 0x51, 0x46, 0x4b, 0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3,
        0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b, 0xbb, 0xb6, 0xa1, 0xac,
        0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0,
        0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48, 0x03, 0x0e, 0x19, 0x14,
        0x37, 0x3a, 0x2d, 0x20, 0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e,
        0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26, 0xbd, 0xb0, 0xa7, 0xaa,
        0x89, 0x84, 0x93, 0x9e, 0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6,
        0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5, 0xbe, 0xb3, 0xa4, 0xa9,
        0x8a, 0x87, 0x90, 0x9d, 0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25,
        0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d, 0xda, 0xd7, 0xc0, 0xcd,
        0xee, 0xe3, 0xf4, 0xf9, 0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91,
        0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29, 0x62, 0x6f, 0x78, 0x75,
        0x56, 0x5b, 0x4c, 0x41, 0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42,
        0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a, 0xb1, 0xbc, 0xab, 0xa6,
        0x85, 0x88, 0x9f, 0x92, 0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa,
        0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8,
        0xeb, 0xe6, 0xf1, 0xfc, 0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44,
        0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c, 0x0c, 0x01, 0x16, 0x1b,
        0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47,
        0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3,
        0x80, 0x8d, 0x9a, 0x97
    );

    private static $GEX = array(
        0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62,
        0x48, 0x46, 0x54, 0x5a, 0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca,
        0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba, 0xdb, 0xd5, 0xc7, 0xc9,
        0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81,
        0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11, 0x4b, 0x45, 0x57, 0x59,
        0x73, 0x7d, 0x6f, 0x61, 0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87,
        0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7, 0x4d, 0x43, 0x51, 0x5f,
        0x75, 0x7b, 0x69, 0x67, 0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17,
        0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c, 0x06, 0x08, 0x1a, 0x14,
        0x3e, 0x30, 0x22, 0x2c, 0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc,
        0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc, 0x41, 0x4f, 0x5d, 0x53,
        0x79, 0x77, 0x65, 0x6b, 0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b,
        0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b, 0xd1, 0xdf, 0xcd, 0xc3,
        0xe9, 0xe7, 0xf5, 0xfb, 0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0,
        0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0, 0x7a, 0x74, 0x66, 0x68,
        0x42, 0x4c, 0x5e, 0x50, 0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20,
        0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e,
        0xa4, 0xaa, 0xb8, 0xb6, 0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26,
        0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56, 0x37, 0x39, 0x2b, 0x25,
        0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d,
        0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5,
        0x9f, 0x91, 0x83, 0x8d
    );
        
        // Key Schedule Core
    private static function core($word,$iteration){
            /* rotate the 32-bit word 8 bits to the left */
            $word = self::rotate($word);
            /* apply S-Box substitution on all 4 parts of the 32-bit word */
            for ($i = 0; $i < 4; ++$i)
                $word[$i] = self::$sbox[$word[$i]];
            /* XOR the output of the rcon operation with i to the first part (leftmost) only */
            $word[0] = $word[0]^self::$Rcon[$iteration];
            return $word;
        }
        
        /* Rijndael's key expansion
         * expands an 128,192,256 key into an 176,208,240 bytes key
         *
         * expandedKey is a pointer to an char array of large enough size
         * key is a pointer to a non-expanded key
         */
    private static function expandKey($key,$size)
        {
            $expandedKeySize = (16*(self::numberOfRounds($size)+1));
            
            /* current expanded keySize, in bytes */
            $currentSize = 0;
            $rconIteration = 1;
            $t = array();   // temporary 4-byte variable
            
            $expandedKey = array();
            for($i = 0;$i < $expandedKeySize;$i++)
                $expandedKey[$i] = 0;
        
            /* set the 16,24,32 bytes of the expanded key to the input key */
            for ($j = 0; $j < $size; $j++)
                $expandedKey[$j] = $key[$j];
            $currentSize += $size;
        
            while ($currentSize < $expandedKeySize)
            {
                /* assign the previous 4 bytes to the temporary value t */
                for ($k = 0; $k < 4; $k++)
                    $t[$k] = $expandedKey[($currentSize - 4) + $k];
        
                /* every 16,24,32 bytes we apply the core schedule to t
                 * and increment rconIteration afterwards
                 */
                if($currentSize % $size == 0)
                    $t = self::core($t, $rconIteration++);
        
                /* For 256-bit keys, we add an extra sbox to the calculation */
                if($size == self::keySize_256 && (($currentSize % $size) == 16))
                    for($l = 0; $l < 4; $l++)
                        $t[$l] = self::$sbox[$t[$l]];
        
                /* We XOR t with the four-byte block 16,24,32 bytes before the new expanded key.
                 * This becomes the next four bytes in the expanded key.
                 */
                for($m = 0; $m < 4; $m++) {
                    $expandedKey[$currentSize] = $expandedKey[$currentSize - $size] ^ $t[$m];
                    $currentSize++;
                }
            }
            return $expandedKey;
        }
        
        // Adds (XORs) the round key to the state
    private static function addRoundKey($state,$roundKey){
            for ($i = 0; $i < 16; $i++)
                $state[$i] = $state[$i] ^ $roundKey[$i];
            return $state;
    }
        
        // Creates a round key from the given expanded key and the
        // position within the expanded key.
    private static function createRoundKey($expandedKey,$roundKeyPointer){
            $roundKey = array();
            for ($i = 0; $i < 4; $i++)
                for ($j = 0; $j < 4; $j++)
                    $roundKey[$j*4+$i] = $expandedKey[$roundKeyPointer + $i*4 + $j];
            return $roundKey;
    }
        
        /* substitute all the values from the state with the value in the SBox
         * using the state value as index for the SBox
         */
    private static function subBytes($state,$isInv){
            for ($i = 0; $i < 16; $i++)
                $state[$i] = $isInv?self::$rsbox[$state[$i]]:self::$sbox[$state[$i]];
            return $state;
    }
        
        /* iterate over the 4 rows and call shiftRow() with that row */
    private static function shiftRows($state,$isInv){
            for ($i = 0; $i < 4; $i++)
                $state = self::shiftRow($state,$i*4, $i,$isInv);
            return $state;
    }
        
        /* each iteration shifts the row to the left by 1 */
    private static function shiftRow($state,$statePointer,$nbr,$isInv){
            for ($i = 0; $i < $nbr; $i++)
            {
                if($isInv)
                {
                    $tmp = $state[$statePointer + 3];
                    for ($j = 3; $j > 0; $j--)
                        $state[$statePointer + $j] = $state[$statePointer + $j-1];
                    $state[$statePointer] = $tmp;
                }
                else
                {
                    $tmp = $state[$statePointer];
                    for ($j = 0; $j < 3; $j++)
                        $state[$statePointer + $j] = $state[$statePointer + $j+1];
                    $state[$statePointer + 3] = $tmp;
                }
            }
            return $state;
    }

        // galois multipication of the 4x4 matrix
    private static function mixColumns($state,$isInv){
        $t = array();
        
        if (!$isInv) {
            for ($c = 0; $c < 4; $c++) {
                $t[   $c] = self::$G2X[$state[$c]] ^ self::$G3X[$state[4+$c]] ^            $state[8+$c]  ^            $state[12+$c];
                $t[ 4+$c] =            $state[$c]  ^ self::$G2X[$state[4+$c]] ^ self::$G3X[$state[8+$c]] ^            $state[12+$c];
                $t[ 8+$c] =            $state[$c]  ^            $state[4+$c]  ^ self::$G2X[$state[8+$c]] ^ self::$G3X[$state[12+$c]];
                $t[12+$c] = self::$G3X[$state[$c]] ^            $state[4+$c]  ^            $state[8+$c]  ^ self::$G2X[$state[12+$c]];
            }
        }else {
            for ($c = 0; $c < 4; $c++) {
        $t[   $c] = self::$GEX[$state[$c]] ^ self::$GBX[$state[4+$c]] ^ self::$GDX[$state[8+$c]] ^ self::$G9X[$state[12+$c]];
        $t[ 4+$c] = self::$G9X[$state[$c]] ^ self::$GEX[$state[4+$c]] ^ self::$GBX[$state[8+$c]] ^ self::$GDX[$state[12+$c]];
        $t[ 8+$c] = self::$GDX[$state[$c]] ^ self::$G9X[$state[4+$c]] ^ self::$GEX[$state[8+$c]] ^ self::$GBX[$state[12+$c]];
        $t[12+$c] = self::$GBX[$state[$c]] ^ self::$GDX[$state[4+$c]] ^ self::$G9X[$state[8+$c]] ^ self::$GEX[$state[12+$c]];
    }        

}
        
        return $t;
    }

        // applies the 4 operations of the forward round in sequence
    private static function round($state, $roundKey){
            $state = self::subBytes($state,false);
            $state = self::shiftRows($state,false);
            $state = self::mixColumns($state,false);
            $state = self::addRoundKey($state, $roundKey);
            return $state;
    }
        
        // applies the 4 operations of the inverse round in sequence
    private static function invRound($state,$roundKey){
            $state = self::shiftRows($state,true);
            $state = self::subBytes($state,true);
            $state = self::addRoundKey($state, $roundKey);
            $state = self::mixColumns($state,true);
            return $state;
    }
        
        /*
         * Perform the initial operations, the standard round, and the final operations
         * of the forward aes, creating a round key for each round
         */
    private static function main($state,$expandedKey,$nbrRounds){
            $state = self::addRoundKey($state, self::createRoundKey($expandedKey,0));
            for ($i = 1; $i < $nbrRounds; $i++)
                $state = self::round($state, self::createRoundKey($expandedKey,16*$i));
            $state = self::subBytes($state,false);
            $state = self::shiftRows($state,false);
            $state = self::addRoundKey($state, self::createRoundKey($expandedKey,16*$nbrRounds));
            return $state;
    }
        
        /*
         * Perform the initial operations, the standard round, and the final operations
         * of the inverse aes, creating a round key for each round
         */
    private static function invMain($state, $expandedKey, $nbrRounds){
            $state = self::addRoundKey($state, self::createRoundKey($expandedKey,16*$nbrRounds));
            for ($i = $nbrRounds-1; $i > 0; $i--)
                $state = self::invRound($state, self::createRoundKey($expandedKey,16*$i));
            $state = self::shiftRows($state,true);
            $state = self::subBytes($state,true);
            $state = self::addRoundKey($state, self::createRoundKey($expandedKey,0));
            return $state;
    }

    private static function numberOfRounds($size){
            $nbrRounds;
            switch ($size) /* set the number of rounds */
            {
                case self::keySize_128:
                    $nbrRounds = 10;
                    break;
                case self::keySize_192:
                    $nbrRounds = 12;
                    break;
                case self::keySize_256:
                    $nbrRounds = 14;
                    break;
                default:
                    return null;
                    break;
            }
            return $nbrRounds;
    }
        
        // encrypts a 128 bit input block against the given key of size specified
    private static function encryptBlock($input,$key,$size){
            $output = array();
            $block = array(); /* the 128 bit block to encode */
            $nbrRounds = self::numberOfRounds($size);
            /* Set the block values, for the block:
             * a0,0 a0,1 a0,2 a0,3
             * a1,0 a1,1 a1,2 a1,3
             * a2,0 a2,1 a2,2 a2,3
             * a3,0 a3,1 a3,2 a3,3
             * the mapping order is a0,0 a1,0 a2,0 a3,0 a0,1 a1,1 ... a2,3 a3,3
             */
            for ($i = 0; $i < 4; $i++) /* iterate over the columns */
                for ($j = 0; $j < 4; $j++) /* iterate over the rows */
                    $block[($i+($j*4))] = $input[($i*4)+$j];
        
            /* expand the key into an 176, 208, 240 bytes key */
            $expandedKey = self::expandKey($key, $size); /* the expanded key */
            /* encrypt the block using the expandedKey */
            $block = self::main($block, $expandedKey, $nbrRounds);
            for ($k = 0; $k < 4; $k++) /* unmap the block again into the output */
                for ($l = 0; $l < 4; $l++) /* iterate over the rows */
                    $output[($k*4)+$l] = $block[($k+($l*4))];
            return $output;
    }
        
        // decrypts a 128 bit input block against the given key of size specified
    private static function decryptBlock($input, $key, $size){
            $output = array();
            $block = array(); /* the 128 bit block to decode */
            $nbrRounds = self::numberOfRounds($size);
            /* Set the block values, for the block:
             * a0,0 a0,1 a0,2 a0,3
             * a1,0 a1,1 a1,2 a1,3
             * a2,0 a2,1 a2,2 a2,3
             * a3,0 a3,1 a3,2 a3,3
             * the mapping order is a0,0 a1,0 a2,0 a3,0 a0,1 a1,1 ... a2,3 a3,3
             */
            for ($i = 0; $i < 4; $i++) /* iterate over the columns */
                for ($j = 0; $j < 4; $j++) /* iterate over the rows */
                    $block[($i+($j*4))] = $input[($i*4)+$j];
            /* expand the key into an 176, 208, 240 bytes key */
            $expandedKey = self::expandKey($key, $size);
            /* decrypt the block using the expandedKey */
            $block = self::invMain($block, $expandedKey, $nbrRounds);
            for ($k = 0; $k < 4; $k++)/* unmap the block again into the output */
                for ($l = 0; $l < 4; $l++)/* iterate over the rows */
                    $output[($k*4)+$l] = $block[($k+($l*4))];
            return $output;
    }
    /*
     * END AES SECTION
     */
     
    /*
     * START MODE OF OPERATION SECTION
     */
    //structure of supported modes of operation
    const modeOfOperation_OFB = 0;
    const modeOfOperation_CFB = 1;
    const modeOfOperation_CBC = 2;
    
    // gets a properly padded block
    private static function getPaddedBlock($bytesIn,$start,$end,$mode){
        if($end - $start > 16)
            $end = $start + 16;
        
        $xarray = array_slice($bytesIn, $start, $end-$start);
        
        $cpad = 16 - count($xarray);
        
        while(count($xarray) < 16){
            array_push($xarray, $cpad);
        }
        
        return $xarray;
    }
    
    /*
     * Mode of Operation Encryption
     * bytesIn - Input String as array of bytes
     * mode - mode of type modeOfOperation
     * key - a number array of length 'size'
     * size - the bit length of the key
     * iv - the 128 bit number array Initialization Vector
     */
    public static function encrypt($bytesIn, $mode, $key, $size, $iv){
        if(count($key)%$size)
        {
            throw new Exception('Key length does not match specified size.');
        }
        if(count($iv)%16)
        {
            throw new Exception('iv length must be 128 bits.');
        }
        // the AES input/output
        $byteArray = array();
        $input = array();
        $output = array();
        $ciphertext = array();
        $cipherOut = array();
        // char firstRound
        $firstRound = true;
        if ($bytesIn !== null)
        {
            for ($j = 0;$j < ceil(count($bytesIn)/16); $j++)
            {
                $start = $j*16;
                $end = $j*16+16;
                if($j*16+16 > count($bytesIn))
                    $end = count($bytesIn);
                $byteArray = self::getPaddedBlock($bytesIn,$start,$end,$mode);
                if ($mode == self::modeOfOperation_CFB)
                {
                    if ($firstRound)
                    {
                        $output = self::encryptBlock($iv, $key, $size);
                        $firstRound = false;
                    }
                    else
                        $output = self::encryptBlock($input, $key, $size);
                    for ($i = 0; $i < 16; $i++)
                        $ciphertext[$i] = $byteArray[$i] ^ $output[$i];
                    for($k = 0;$k < $end-$start;$k++)
                        array_push($cipherOut, $ciphertext[$k]);
                    $input = $ciphertext;
                }
                else if ($mode == self::modeOfOperation_OFB)
                {
                    if ($firstRound)
                    {
                        $output = self::encryptBlock($iv, $key, $size);
                        $firstRound = false;
                    }
                    else
                        $output = self::encryptBlock($input, $key, $size);
                    for ($i = 0; $i < 16; $i++)
                        $ciphertext[$i] = $byteArray[$i] ^ $output[$i];
                    for($k = 0;$k < $end-$start;$k++)
                        array_push($cipherOut, $ciphertext[$k]);
                    $input = $output;
                }
                else if ($mode == self::modeOfOperation_CBC)
                {
                    for ($i = 0; $i < 16; $i++)
                        $input[$i] = $byteArray[$i] ^ (($firstRound) ? $iv[$i] : $ciphertext[$i]);
                    $firstRound = false;
                    $ciphertext = self::encryptBlock($input, $key, $size);
                    // always 16 bytes because of the padding for CBC
                    for($k = 0;$k < 16;$k++)
                        array_push($cipherOut, $ciphertext[$k]);
                }
            }
        }
        return array('mode' => $mode, 'originalsize' => count($bytesIn), 'cipher' => $cipherOut);
    }
    
    /*
     * Mode of Operation Decryption
     * cipherIn - Encrypted String as array of bytes
     * originalsize - The unencrypted string length - required for CBC
     * mode - mode of type modeOfOperation
     * key - a number array of length 'size'
     * size - the bit length of the key
     * iv - the 128 bit number array Initialization Vector
     */
    public static function decrypt($cipherIn,$originalsize,$mode,$key,$size,$iv)
    {
        if(count($key)%$size)
        {
            throw new Exception('Key length does not match specified size.');
            return null;
        }
        if(count($iv)%16)
        {
            throw new Exception('iv length must be 128 bits.');
        }
        // the AES input/output
        $ciphertext = array();
        $input = array();
        $output = array();
        $byteArray = array();
        $bytesOut = array();
        // char firstRound
        $firstRound = true;
        if ($cipherIn !== null)
        {
            for ($j = 0;$j < ceil(count($cipherIn)/16); $j++)
            {
                $start = $j*16;
                $end = $j*16+16;
                if($j*16+16 > count($cipherIn))
                    $end = count($cipherIn);
                $ciphertext = self::getPaddedBlock($cipherIn,$start,$end,$mode);
                if ($mode == self::modeOfOperation_CFB)
                {
                    if ($firstRound)
                    {
                        $output = self::encryptBlock($iv, $key, $size);
                        $firstRound = false;
                    }
                    else
                        $output = self::encryptBlock($input, $key, $size);
                    for ($i = 0; $i < 16; $i++)
                        $byteArray[$i] = $output[$i] ^ $ciphertext[$i];
                    for($k = 0;$k < $end-$start;$k++)
                        array_push($bytesOut, $byteArray[$k]);
                    $input = $ciphertext;
                }
                else if ($mode == self::modeOfOperation_OFB)
                {
                    if ($firstRound)
                    {
                        $output = self::encryptBlock($iv, $key, $size);
                        $firstRound = false;
                    }
                    else
                        $output = self::encryptBlock($input, $key, $size);
                    for ($i = 0; $i < 16; $i++)
                        $byteArray[$i] = $output[$i] ^ $ciphertext[$i];
                    for($k = 0;$k < $end-$start;$k++)
                        array_push($bytesOut, $byteArray[$k]);
                    $input = $output;
                }
                else if($mode == self::modeOfOperation_CBC)
                {
                    $output = self::decryptBlock($ciphertext, $key, $size);
                    for ($i = 0; $i < 16; $i++)
                        $byteArray[$i] = (($firstRound) ? $iv[$i] : $input[$i]) ^ $output[$i];
                    $firstRound = false;
                    if ($originalsize < $end)
                        for($k = 0;$k < $originalsize-$start;$k++)
                            array_push($bytesOut, $byteArray[$k]);
                    else
                        for($k = 0;$k < $end-$start;$k++)
                            array_push($bytesOut, $byteArray[$k]);
                    $input = $ciphertext;
                }
            }
        }
        return $bytesOut;
    }
    /*
     * END MODE OF OPERATION SECTION
     */
}

?>

4 (2021.03.19 12:51:20 отредактировано smsbox3)

Re: Защита сайтов от парсинга

Че то я не понимаю, как использовать этот код на php.
В javascript есть вызов slowAES.decrypt(c,2,a,b) - c,2,a,b у нас есть в наличии, но

public static function decrypt($cipherIn,$originalsize,$mode,$key,$size,$iv) требует больше параметров.
$cipherIn - зашифрованная строка байтов
$originalsiz - длина незашифрованной строки
$mode - режим какой-то
$key -  числовой массив длины $size
$size - та самая длина
$iv - вектор инициализации 128-битного числового массива ?

Длину незашифрованной строки мы видим в браузере в куке __test=7b2145b094a3f1881cdc4d25d1072f10 - 32 байт

Аналогичная в javascript
/*
     * Mode of Operation Decryption
     * cipherIn - Encrypted String as array of bytes
     * originalsize - The unencrypted string length - required for CBC
     * mode - mode of type modeOfOperation
     * key - a number array of length 'size'
     * size - the bit length of the key
     * iv - the 128 bit number array Initialization Vector
     */
    decrypt:function(cipherIn,mode,key,iv)

похоже я не туда смотрю.

slowAES.decrypt(c,2,a,b)
decrypt:function(cipherIn,mode,key,iv)

cipherIn это c
mode это 2
key это a
iv это b

в php
decrypt($cipherIn,$originalsize,$mode,$key,$size,$iv)

дополнительно есть два размера результирующей строки (вроде знаем из кука) и длина ключа - тоже можно  просчитать, но зачем тогда передавать?
$originalsize и $size в нашем случае 32 байта.

но как это все собрать в рабочий код? С объектным php я не сталкивался.

5 (2021.03.20 11:55:20 отредактировано smsbox3)

Re: Защита сайтов от парсинга

Сегодня попробую вот такой код запустить

$cip="ПеременнаяС";
$mode=2;
$key="переменнаяА";
$iv="переменнаяB";
$originalsize=32;
$size=32;
$a=new AES;
$b=$a-> decrypt($cipherIn,$originalsize,$mode,$key,$size,$iv);
echo $b;

Так не работает, надо преобразовывать типа в правильное значение. 16 ричные числа передаются как массив. В javascript за это отвечает функция

function toNumbers(d){var e=[];d.replace(/(..)/g,function(d){e.push(parseInt(d,16))});return e}

Вот ее и надо будет реализовывать похоже. Только не понятно пока, что она делает.

Вот так мы это можем сделать
$cip=str_split($c); $key=str_split($k);  $iv=str_split($i);

Передаем, вызываем - возвращает массив десятичных чисел, теперь его надо собрать в 16 ричную строку и должен получиться правильный кук

Получилось, но не то, слишком много цифр, не 32 числа в результате, а 16 должно быть, 16, каждое число 2 байта. Может и на входе так же?

Надо будет вот это загрузить в отладчик и поставив точки остановки определить, какие значения реально передаются

<html><body><script type="text/javascript" src="http://smsbox.qlihost.ru/aes.js" ></script><script>function toNumbers(d){var e=[];d.replace(/(..)/g,function(d){e.push(parseInt(d,16))});return e}function toHex(){for(var d=[],d=1==arguments.length&&arguments[0].constructor==Array?arguments[0]:arguments,e="",f=0;f<d.length;f++)e+=(16>d[f]?"0":"")+d[f].toString(16);return e.toLowerCase()}var a=toNumbers("f655ba9d09a112d4968c63579db590b4"),b=toNumbers("98344c2eee86c3994890592585b49f80"),c=toNumbers("7911eb502bb09dd5dc9a3a65f304bd95");document.cookie="__test="+toHex(slowAES.decrypt(c,2,a,b))+"; expires=Thu, 31-Dec-37 23:55:55 GMT; path=/"; location.href="http://smsbox.qlihost.ru/you/new/g2.php?v=CHdGju51-Rk&i=1";</script><noscript>This site requires Javascript to work, please enable Javascript in your browser or use a browser with Javascript support</noscript></body></html>

6

Re: Защита сайтов от парсинга

Все значения совпадают, javascript в отладчике по данных значениях переменных a,b,c выдает fe73174e21f1dfca432612b851462ced и php выдает fe73174e21f1dfca432612b851462ced.
Осталось сформировать кук и подсунут в curl, но это уже завтра буду делать.
Вывод - защиту использующую src="/aes.js" можно легко обходить на php, осталось другие защиты собрать в одну библиотеку и серый волк будет не страшен :)

Re: Защита сайтов от парсинга

Добрый день! С недавних пор ресурс https:\\movix.ru перестал нормально открываться в скрипте на HMS. Вместо ожидаемого содержимого мы получаем (ниже фрагмент):

+ открыть спойлер
<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <meta http-equiv="refresh" content="10;URL=/ciez2a">
</head>
<body>
  <script type="text/javascript">
function md5cycle(e,t){var i=e[0],a=e[1],r=e[2],n=e[3];a=ii(a=ii(a=ii(a=ii(a=hh(a=hh(a=hh(a=hh(a=gg(a=gg(a=gg(a=gg(a=ff(a=ff(a=ff(a=ff(a,r=ff(r,n=ff(n,i=ff(i,a,r,n,t[0],7,-680876936),a,r,t[1],12,-389564586),i,a,t[2],17,606105819),n,i,t[3],22,-

    .    .    .    .    .    .    .    .        .    .

 return this.getKey().getPublicBaseKeyB64()},t.version="3.0.0-rc.1",t}();window.JSEncrypt=rt,t.JSEncrypt=rt,t.default=rt,Object.defineProperty(t,"__esModule",{value:!0})});

var ipp = {
    decrypt:function()
    {
                var decrypt = new JSEncrypt();
                decrypt.setPrivateKey("MIIkKQIBAAKCCAEArbPJ2oT3hg+ccBRS5/4QqyvCCG589gxVdyl5itf+6n3EXxv0wff1XFKGCqsufCTL+uz7Ipk604cnlf68Qn1rNaE3D/3l61n60IGbO6uIIYUt9SRW2pzltFTAV2bQl50rCEOCKkayhuD54
    .    .    .    .    .    .    .    .    .    
 =");
    },
    setCookie:function()
    {
        document.cookie="ipp_key=" + this.decrypt() + "; Path=/";
        document.cookie="ipp_uid=1658911709518/ZBBnifBFHnfNPXFL/ghEDsPYDnQJyScQ0QjP5YA==; Expires=Tue, 31 Dec 2030 23:59:59 GMT; Path=/";
    },
    makeUrl:function(url)
    {
        url += "fa821dba_ipp_key=v1658911709518_v33947245b95adc7a72e273_tOQNDAkdYeY7pwj8FTKlrg=" + this.decrypt() + "&" + "fa821dba_ipp_uid=1658911709518_ZBBnifBFHnfNPXFL_ghEDsPYDnQJyScQ0QjP5YA";
        return url;
        }
};


    (new Fingerprint2).get(function(e,t){
      salt="857372072";
      document.cookie="ipp_sign="+e+"_"+salt+"_"+md5(e+salt)+"; expires=Tue, 31 Dec 2030 23:59:59 GMT; path=/;";
      ipp.setCookie();
      window.location.href = "https://movix.ru/site/login?" + window.location.hash;
    })
  </script>
</body>
</html>

В браузере ссылка открывается нормально. Прошу помочь, что нужно сделать, чтобы в скрипте открыть ссылку в нормальном виде?