<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Неофициальный форум DLNA Home Media Server &mdash; Защита сайтов от парсинга]]></title>
		<link>https://hms.lostcut.net/viewtopic.php?id=842</link>
		<atom:link href="https://hms.lostcut.net/extern.php?action=feed&amp;tid=842&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «Защита сайтов от парсинга».]]></description>
		<lastBuildDate>Wed, 27 Jul 2022 08:56:30 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Re: Защита сайтов от парсинга]]></title>
			<link>https://hms.lostcut.net/viewtopic.php?pid=18091#p18091</link>
			<description><![CDATA[<p>Добрый день! С недавних пор ресурс https:\\movix.ru перестал нормально открываться в скрипте на HMS. Вместо ожидаемого содержимого мы получаем (ниже фрагмент):<br /></p><div class="fancy_spoiler_switcher"><div class="fancy_spoiler_switcher_header" data-lang-open="открыть спойлер" data-lang-close="скрыть спойлер"><strong>+</strong>&nbsp;открыть спойлер</div><div class="fancy_spoiler"><div class="codebox"><pre><code>&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot;&gt;
  &lt;meta http-equiv=&quot;refresh&quot; content=&quot;10;URL=/ciez2a&quot;&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;script type=&quot;text/javascript&quot;&gt;
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=&quot;3.0.0-rc.1&quot;,t}();window.JSEncrypt=rt,t.JSEncrypt=rt,t.default=rt,Object.defineProperty(t,&quot;__esModule&quot;,{value:!0})});

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


    (new Fingerprint2).get(function(e,t){
      salt=&quot;857372072&quot;;
      document.cookie=&quot;ipp_sign=&quot;+e+&quot;_&quot;+salt+&quot;_&quot;+md5(e+salt)+&quot;; expires=Tue, 31 Dec 2030 23:59:59 GMT; path=/;&quot;;
      ipp.setCookie();
      window.location.href = &quot;https://movix.ru/site/login?&quot; + window.location.hash;
    })
  &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre></div></div></div><p>В браузере ссылка открывается нормально. Прошу помочь, что нужно сделать, чтобы в скрипте открыть ссылку в нормальном виде?</p>]]></description>
			<author><![CDATA[null@example.com (radik_sabirov)]]></author>
			<pubDate>Wed, 27 Jul 2022 08:56:30 +0000</pubDate>
			<guid>https://hms.lostcut.net/viewtopic.php?pid=18091#p18091</guid>
		</item>
		<item>
			<title><![CDATA[Re: Защита сайтов от парсинга]]></title>
			<link>https://hms.lostcut.net/viewtopic.php?pid=17813#p17813</link>
			<description><![CDATA[<p>Все значения совпадают, javascript в отладчике по данных значениях переменных a,b,c выдает fe73174e21f1dfca432612b851462ced и php выдает fe73174e21f1dfca432612b851462ced.<br />Осталось сформировать кук и подсунут в curl, но это уже завтра буду делать.<br />Вывод - защиту использующую src=&quot;/aes.js&quot; можно легко обходить на php, осталось другие защиты собрать в одну библиотеку и серый волк будет не страшен <img src="https://hms.lostcut.net/extensions/k_smiles/img/ab.gif" alt=":)" /></p>]]></description>
			<author><![CDATA[null@example.com (smsbox3)]]></author>
			<pubDate>Sat, 20 Mar 2021 09:24:04 +0000</pubDate>
			<guid>https://hms.lostcut.net/viewtopic.php?pid=17813#p17813</guid>
		</item>
		<item>
			<title><![CDATA[Re: Защита сайтов от парсинга]]></title>
			<link>https://hms.lostcut.net/viewtopic.php?pid=17812#p17812</link>
			<description><![CDATA[<p>Сегодня попробую вот такой код запустить<br /></p><div class="codebox"><pre><code>$cip=&quot;ПеременнаяС&quot;;
$mode=2;
$key=&quot;переменнаяА&quot;;
$iv=&quot;переменнаяB&quot;;
$originalsize=32;
$size=32;
$a=new AES;
$b=$a-&gt; decrypt($cipherIn,$originalsize,$mode,$key,$size,$iv);
echo $b;</code></pre></div><p>Так не работает, надо преобразовывать типа в правильное значение. 16 ричные числа передаются как массив. В javascript за это отвечает функция<br /></p><div class="codebox"><pre><code>function toNumbers(d){var e=[];d.replace(/(..)/g,function(d){e.push(parseInt(d,16))});return e}</code></pre></div><p>Вот ее и надо будет реализовывать похоже. Только не понятно пока, что она делает.</p><p>Вот так мы это можем сделать<br />$cip=str_split($c); $key=str_split($k);&nbsp; $iv=str_split($i);</p><p>Передаем, вызываем - возвращает массив десятичных чисел, теперь его надо собрать в 16 ричную строку и должен получиться правильный кук</p><p>Получилось, но не то, слишком много цифр, не 32 числа в результате, а 16 должно быть, 16, каждое число 2 байта. Может и на входе так же?</p><p>Надо будет вот это загрузить в отладчик и поставив точки остановки определить, какие значения реально передаются<br /></p><div class="codebox"><pre><code>&lt;html&gt;&lt;body&gt;&lt;script type=&quot;text/javascript&quot; src=&quot;http://smsbox.qlihost.ru/aes.js&quot; &gt;&lt;/script&gt;&lt;script&gt;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&amp;&amp;arguments[0].constructor==Array?arguments[0]:arguments,e=&quot;&quot;,f=0;f&lt;d.length;f++)e+=(16&gt;d[f]?&quot;0&quot;:&quot;&quot;)+d[f].toString(16);return e.toLowerCase()}var a=toNumbers(&quot;f655ba9d09a112d4968c63579db590b4&quot;),b=toNumbers(&quot;98344c2eee86c3994890592585b49f80&quot;),c=toNumbers(&quot;7911eb502bb09dd5dc9a3a65f304bd95&quot;);document.cookie=&quot;__test=&quot;+toHex(slowAES.decrypt(c,2,a,b))+&quot;; expires=Thu, 31-Dec-37 23:55:55 GMT; path=/&quot;; location.href=&quot;http://smsbox.qlihost.ru/you/new/g2.php?v=CHdGju51-Rk&amp;i=1&quot;;&lt;/script&gt;&lt;noscript&gt;This site requires Javascript to work, please enable Javascript in your browser or use a browser with Javascript support&lt;/noscript&gt;&lt;/body&gt;&lt;/html&gt;</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (smsbox3)]]></author>
			<pubDate>Sat, 20 Mar 2021 06:56:01 +0000</pubDate>
			<guid>https://hms.lostcut.net/viewtopic.php?pid=17812#p17812</guid>
		</item>
		<item>
			<title><![CDATA[Re: Защита сайтов от парсинга]]></title>
			<link>https://hms.lostcut.net/viewtopic.php?pid=17810#p17810</link>
			<description><![CDATA[<p>Че то я не понимаю, как использовать этот код на php.<br />В javascript есть вызов slowAES.decrypt(c,2,a,b) - c,2,a,b у нас есть в наличии, но </p><p>public static function decrypt($cipherIn,$originalsize,$mode,$key,$size,$iv) требует больше параметров.<br />$cipherIn - зашифрованная строка байтов<br />$originalsiz - длина незашифрованной строки<br />$mode - режим какой-то<br />$key -&nbsp; числовой массив длины $size<br />$size - та самая длина<br />$iv - вектор инициализации 128-битного числового массива ?</p><p>Длину незашифрованной строки мы видим в браузере в куке __test=7b2145b094a3f1881cdc4d25d1072f10 - 32 байт</p><p>Аналогичная в javascript<br /> /*<br />&nbsp; &nbsp; &nbsp;* Mode of Operation Decryption<br />&nbsp; &nbsp; &nbsp;* cipherIn - Encrypted String as array of bytes<br />&nbsp; &nbsp; &nbsp;* originalsize - The unencrypted string length - required for CBC<br />&nbsp; &nbsp; &nbsp;* mode - mode of type modeOfOperation<br />&nbsp; &nbsp; &nbsp;* key - a number array of length &#039;size&#039;<br />&nbsp; &nbsp; &nbsp;* size - the bit length of the key<br />&nbsp; &nbsp; &nbsp;* iv - the 128 bit number array Initialization Vector<br />&nbsp; &nbsp; &nbsp;*/<br />&nbsp; &nbsp; decrypt:function(cipherIn,mode,key,iv)</p><p>похоже я не туда смотрю.</p><div class="codebox"><pre><code>slowAES.decrypt(c,2,a,b)
decrypt:function(cipherIn,mode,key,iv)</code></pre></div><p>cipherIn это c<br />mode это 2<br />key это a<br />iv это b</p><p>в php<br />decrypt($cipherIn,$originalsize,$mode,$key,$size,$iv)</p><p>дополнительно есть два размера результирующей строки (вроде знаем из кука) и длина ключа - тоже можно&nbsp; просчитать, но зачем тогда передавать?<br />$originalsize и $size в нашем случае 32 байта.</p><p>но как это все собрать в рабочий код? С объектным php я не сталкивался.</p>]]></description>
			<author><![CDATA[null@example.com (smsbox3)]]></author>
			<pubDate>Fri, 19 Mar 2021 09:19:04 +0000</pubDate>
			<guid>https://hms.lostcut.net/viewtopic.php?pid=17810#p17810</guid>
		</item>
		<item>
			<title><![CDATA[Re: Защита сайтов от парсинга]]></title>
			<link>https://hms.lostcut.net/viewtopic.php?pid=17809#p17809</link>
			<description><![CDATA[<p>Оказывается эта функция давно реализована на php</p><div class="fancy_spoiler_switcher"><div class="fancy_spoiler_switcher_header" data-lang-open="открыть спойлер" data-lang-close="скрыть спойлер"><strong>+</strong>&nbsp;открыть спойлер</div><div class="fancy_spoiler"><div class="codebox"><pre><code>&lt;?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 &lt; 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 &lt; 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&#039;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 &lt; $expandedKeySize;$i++)
                $expandedKey[$i] = 0;
        
            /* set the 16,24,32 bytes of the expanded key to the input key */
            for ($j = 0; $j &lt; $size; $j++)
                $expandedKey[$j] = $key[$j];
            $currentSize += $size;
        
            while ($currentSize &lt; $expandedKeySize)
            {
                /* assign the previous 4 bytes to the temporary value t */
                for ($k = 0; $k &lt; 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 &amp;&amp; (($currentSize % $size) == 16))
                    for($l = 0; $l &lt; 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 &lt; 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 &lt; 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 &lt; 4; $i++)
                for ($j = 0; $j &lt; 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 &lt; 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 &lt; 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 &lt; $nbr; $i++)
            {
                if($isInv)
                {
                    $tmp = $state[$statePointer + 3];
                    for ($j = 3; $j &gt; 0; $j--)
                        $state[$statePointer + $j] = $state[$statePointer + $j-1];
                    $state[$statePointer] = $tmp;
                }
                else
                {
                    $tmp = $state[$statePointer];
                    for ($j = 0; $j &lt; 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 &lt; 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 &lt; 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 &lt; $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 &gt; 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 &lt; 4; $i++) /* iterate over the columns */
                for ($j = 0; $j &lt; 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 &lt; 4; $k++) /* unmap the block again into the output */
                for ($l = 0; $l &lt; 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 &lt; 4; $i++) /* iterate over the columns */
                for ($j = 0; $j &lt; 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 &lt; 4; $k++)/* unmap the block again into the output */
                for ($l = 0; $l &lt; 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 &gt; 16)
            $end = $start + 16;
        
        $xarray = array_slice($bytesIn, $start, $end-$start);
        
        $cpad = 16 - count($xarray);
        
        while(count($xarray) &lt; 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 &#039;size&#039;
     * 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(&#039;Key length does not match specified size.&#039;);
        }
        if(count($iv)%16)
        {
            throw new Exception(&#039;iv length must be 128 bits.&#039;);
        }
        // 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 &lt; ceil(count($bytesIn)/16); $j++)
            {
                $start = $j*16;
                $end = $j*16+16;
                if($j*16+16 &gt; 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 &lt; 16; $i++)
                        $ciphertext[$i] = $byteArray[$i] ^ $output[$i];
                    for($k = 0;$k &lt; $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 &lt; 16; $i++)
                        $ciphertext[$i] = $byteArray[$i] ^ $output[$i];
                    for($k = 0;$k &lt; $end-$start;$k++)
                        array_push($cipherOut, $ciphertext[$k]);
                    $input = $output;
                }
                else if ($mode == self::modeOfOperation_CBC)
                {
                    for ($i = 0; $i &lt; 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 &lt; 16;$k++)
                        array_push($cipherOut, $ciphertext[$k]);
                }
            }
        }
        return array(&#039;mode&#039; =&gt; $mode, &#039;originalsize&#039; =&gt; count($bytesIn), &#039;cipher&#039; =&gt; $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 &#039;size&#039;
     * 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(&#039;Key length does not match specified size.&#039;);
            return null;
        }
        if(count($iv)%16)
        {
            throw new Exception(&#039;iv length must be 128 bits.&#039;);
        }
        // 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 &lt; ceil(count($cipherIn)/16); $j++)
            {
                $start = $j*16;
                $end = $j*16+16;
                if($j*16+16 &gt; 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 &lt; 16; $i++)
                        $byteArray[$i] = $output[$i] ^ $ciphertext[$i];
                    for($k = 0;$k &lt; $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 &lt; 16; $i++)
                        $byteArray[$i] = $output[$i] ^ $ciphertext[$i];
                    for($k = 0;$k &lt; $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 &lt; 16; $i++)
                        $byteArray[$i] = (($firstRound) ? $iv[$i] : $input[$i]) ^ $output[$i];
                    $firstRound = false;
                    if ($originalsize &lt; $end)
                        for($k = 0;$k &lt; $originalsize-$start;$k++)
                            array_push($bytesOut, $byteArray[$k]);
                    else
                        for($k = 0;$k &lt; $end-$start;$k++)
                            array_push($bytesOut, $byteArray[$k]);
                    $input = $ciphertext;
                }
            }
        }
        return $bytesOut;
    }
    /*
     * END MODE OF OPERATION SECTION
     */
}

?&gt;</code></pre></div></div></div>]]></description>
			<author><![CDATA[null@example.com (smsbox3)]]></author>
			<pubDate>Fri, 19 Mar 2021 06:02:08 +0000</pubDate>
			<guid>https://hms.lostcut.net/viewtopic.php?pid=17809#p17809</guid>
		</item>
		<item>
			<title><![CDATA[Re: Защита сайтов от парсинга]]></title>
			<link>https://hms.lostcut.net/viewtopic.php?pid=17808#p17808</link>
			<description><![CDATA[<p>Нашел по этому вопрос заметку </p><div class="codebox"><pre><code>https://qna.habr.com/q/627776</code></pre></div><p> Там С имеет другое значение </p><div class="codebox"><pre><code>c = toNumbers(&quot;a37dcb8d65f1b5d98d196ec3731b3e74&quot;);</code></pre></div><p>, а и b те же, что у меня.<br />Еще в одном месте посмотрел<br /></p><div class="codebox"><pre><code>var a = toNumbers(&quot;f655ba9d09a112d4968c63579db590b4&quot;),
                b = toNumbers(&quot;98344c2eee86c3994890592585b49f80&quot;),
                c = toNumbers(&quot;568c5a3227852f5cc113bd8ba3b64dc3&quot;);</code></pre></div><p>а и b теже, с другой.</p><p>проверил запросом с другого сервера - точно c=toNumbers(&quot;351626b6f88c85079e9282d14037064d&quot;<br />Выходит это привязка к ip</p>]]></description>
			<author><![CDATA[null@example.com (smsbox3)]]></author>
			<pubDate>Fri, 19 Mar 2021 05:53:08 +0000</pubDate>
			<guid>https://hms.lostcut.net/viewtopic.php?pid=17808#p17808</guid>
		</item>
		<item>
			<title><![CDATA[Защита сайтов от парсинга]]></title>
			<link>https://hms.lostcut.net/viewtopic.php?pid=17807#p17807</link>
			<description><![CDATA[<p>Последнее время все больше сайтов переходят на защиту javascriptом от парсинга и это становится проблемой.<br /> Для примера есть бесплатный хостиг, который представлен под разными названиями (похоже там просто арендуют уже готовые решения разные организации и предлагают совершенно идентичный бесплатный хостинг), но физически одни сервера, одно ПО, одна и защита.<br />Так вот например у меня есть такой запрос </p><div class="codebox"><pre><code>http://smsbox.qlihost.ru/you/new/g2.php?v=CHdGju51-Rk</code></pre></div><p>, в браузере видим тестовый ответ, но если попробует считать средствами php возвращает ненужный javascript, с которым надо что-то делать.<br /></p><div class="fancy_spoiler_switcher"><div class="fancy_spoiler_switcher_header" data-lang-open="открыть спойлер" data-lang-close="скрыть спойлер"><strong>+</strong>&nbsp;открыть спойлер</div><div class="fancy_spoiler"><div class="codebox"><pre><code>&lt;html&gt;&lt;body&gt;&lt;script type=&quot;text/javascript&quot; src=&quot;/aes.js&quot; &gt;&lt;/script&gt;&lt;script&gt;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&amp;&amp;arguments[0].constructor==Array?arguments[0]:arguments,e=&quot;&quot;,f=0;f&lt;d.length;f++)e+=(16&gt;d[f]?&quot;0&quot;:&quot;&quot;)+d[f].toString(16);return e.toLowerCase()}var a=toNumbers(&quot;f655ba9d09a112d4968c63579db590b4&quot;),b=toNumbers(&quot;98344c2eee86c3994890592585b49f80&quot;),c=toNumbers(&quot;7911eb502bb09dd5dc9a3a65f304bd95&quot;);document.cookie=&quot;__test=&quot;+toHex(slowAES.decrypt(c,2,a,b))+&quot;; expires=Thu, 31-Dec-37 23:55:55 GMT; path=/&quot;; location.href=&quot;http://smsbox.qlihost.ru/you/new/g2.php?v=CHdGju51-Rk&amp;i=1&quot;;&lt;/script&gt;&lt;noscript&gt;This site requires Javascript to work, please enable Javascript in your browser or use a browser with Javascript support&lt;/noscript&gt;&lt;/body&gt;&lt;/html&gt;</code></pre></div></div></div><p>файлик aes.js скачать не проблема </p><div class="codebox"><pre><code>http://smsbox.qlihost.ru/aes.js</code></pre></div><p> Кстати этим можно проверять хостинг реальный тот самый бесплатный или это что-то другое.</p><p>Что я тут вижу? Устанавливается кук с именем </p><div class="codebox"><pre><code>__test</code></pre></div><p>&nbsp; до 31-Dec-37 23:55:55&nbsp; т.е. в нашем случае вечный.<br />цифры а,b,c неизменны (причем на разных сайтах этого хостинга они те же самые, и похоже не зависят от времени, вчера были те же)<br />Формула функции получения кука -&nbsp; slowAES.decrypt(c,2,a,b) то же неизменна.<br />В браузере я вижу такое значение&nbsp; __test=7b2145b094a3f1881cdc4d25d1072f10 При смене домена на другой бесплатный хостинг остается тот же самый кукис.<br />ту либо к ip привязка, либо вообще случайное число?<br />Если кому-то будет интересно поломать голову, вот ссылка того, что можно попробовать прочитать </p><div class="codebox"><pre><code>http://smsbox.qlihost.ru/you/new/g2.php?v=CHdGju51-Rk</code></pre></div><p> Вот, функция кодирования кукиса (AES - это «симметричный блочный шифр» для шифрования текстов одобрено правительством США для секретной информации до «секретной» - и с длиной ключа 192 или 256, вплоть до «совершенно секретно»)<br /></p><div class="fancy_spoiler_switcher"><div class="fancy_spoiler_switcher_header" data-lang-open="открыть спойлер" data-lang-close="скрыть спойлер"><strong>+</strong>&nbsp;открыть спойлер</div><div class="fancy_spoiler"><div class="codebox"><pre><code>/*
 * 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 &lt; 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 &lt; 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&#039;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 &lt; expandedKeySize;i++)
                expandedKey[i] = 0;
        
            /* set the 16,24,32 bytes of the expanded key to the input key */
            for (var j = 0; j &lt; size; j++)
                expandedKey[j] = key[j];
            currentSize += size;
        
            while (currentSize &lt; expandedKeySize)
            {
                /* assign the previous 4 bytes to the temporary value t */
                for (var k = 0; k &lt; 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 &amp;&amp; ((currentSize % size) == 16))
                    for(var l = 0; l &lt; 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 &lt; 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 &lt; 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 &lt; 4; i++)
                for (var j = 0; j &lt; 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 &lt; 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 &lt; 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 &lt; nbr; i++)
            {
                if(isInv)
                {
                    var tmp = state[statePointer + 3];
                    for (var j = 3; j &gt; 0; j--)
                        state[statePointer + j] = state[statePointer + j-1];
                    state[statePointer] = tmp;
                }
                else
                {
                    var tmp = state[statePointer];
                    for (var j = 0; j &lt; 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 &lt; 8; counter++)
            {
                if((b &amp; 1) == 1)
                    p ^= a;
                if(p &gt; 0x100) p ^= 0x100;
                var hi_bit_set = (a &amp; 0x80); //keep p 8 bit
                a &lt;&lt;= 1;
                if(a &gt; 0x100) a ^= 0x100; //keep a 8 bit
                if(hi_bit_set == 0x80)
                    a ^= 0x1b;
                if(a &gt; 0x100) a ^= 0x100; //keep a 8 bit
                b &gt;&gt;= 1;
                if(b &gt; 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 &lt; 4; i++)
            {
                /* construct one column by iterating over the 4 rows */
                for (var j = 0; j &lt; 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 &lt; 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 &lt; 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 &lt; 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 &gt; 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 &lt; 4; i++) /* iterate over the columns */
                for (var j = 0; j &lt; 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 &lt; 4; k++) /* unmap the block again into the output */
                for (var l = 0; l &lt; 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 &lt; 4; i++) /* iterate over the columns */
                for (var j = 0; j &lt; 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 &lt; 4; k++)/* unmap the block again into the output */
                for (var l = 0; l &lt; 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 &gt; 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 &#039;size&#039;
     * 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 &#039;iv length must be 128 bits.&#039;;
        }
        // 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 &lt; Math.ceil(bytesIn.length/16); j++)
            {
                var start = j*16;
                var end = j*16+16;
                if(j*16+16 &gt; 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 &lt; 16; i++)
                        ciphertext[i] = byteArray[i] ^ output[i];
                    for(var k = 0;k &lt; 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 &lt; 16; i++)
                        ciphertext[i] = byteArray[i] ^ output[i];
                    for(var k = 0;k &lt; end-start;k++)
                        cipherOut.push(ciphertext[k]);
                    input = output;
                }
                else if (mode == this.modeOfOperation.CBC)
                {
                    for (var i = 0; i &lt; 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 &lt; 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 &#039;size&#039;
     * 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 &#039;iv length must be 128 bits.&#039;;
        }
        // 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 &lt; Math.ceil(cipherIn.length/16); j++)
            {
                var start = j*16;
                var end = j*16+16;
                if(j*16+16 &gt; 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 &lt; 16; i++)
                        byteArray[i] = output[i] ^ ciphertext[i];
                    for(var k = 0;k &lt; 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 &lt; 16; i++)
                        byteArray[i] = output[i] ^ ciphertext[i];
                    for(var k = 0;k &lt; 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 &lt; 16; i++)
                        byteArray[i] = ((firstRound) ? iv[i] : input[i]) ^ output[i];
                    firstRound = false;
                    for(var k = 0;k &lt; 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 &lt; padByte; i++) {
            data.push(padByte);
        }
    },
    unpadBytesOut: function(data) {
        var padCount = 0;
        var padByte = -1;
        var blockSize = 16;
        if (data.length &gt; 16) {
        for (var i = data.length - 1; i &gt;= data.length-1 - blockSize; i--) {
            if (data[i] &lt;= blockSize) {
                if (padByte == -1)
                    padByte = data[i];
                if (data[i] != padByte) {
                    padCount = 0;
                    break;
                }
                padCount++;
            } else
                break;
            if (padCount == padByte)
                break;
        }
        if (padCount &gt; 0)
            data.splice(data.length - padCount, padCount);
        }
    }
    /*
     * END MODE OF OPERATION SECTION
     */
};</code></pre></div></div></div>]]></description>
			<author><![CDATA[null@example.com (smsbox3)]]></author>
			<pubDate>Fri, 19 Mar 2021 05:38:50 +0000</pubDate>
			<guid>https://hms.lostcut.net/viewtopic.php?pid=17807#p17807</guid>
		</item>
	</channel>
</rss>
