从字符串创建HTML文档的正确方法?

时间:2011-06-20 04:35:39

标签: php javascript html encryption greasemonkey

首先,我很便宜! :)我买不起我的域名的静态IP,我买不起那些花哨的证书......所以我没有SSL / HTTPS。

我在这里要完成的是推出自己的“HTTP加密”。这是我到目前为止所取得的成就:

  1. 将现有代理脚本(Glype / PHProxy)修改为“加密”(现在为base64)回声输出。 (我将整个内容包装在一个body元素中,顺便说一下)
  2. 编写一个GreaseMonkey脚本来“解密”加密输出。
  3. 这件事适用于简单的网站。但是当我加载复杂的网站(比如浏览器游戏)时,javascripts就会崩溃(顺便说一下,当我关闭加密时脚本可以完美呈现游戏)。

    通过FireBug检查后​​,我注意到head元素的内容被放置在body元素中。这并不总是发生所以我怀疑PHP输出格式错误的输出,但我使用离线工具解码了base64,HTML看起来还不错。

    以下是PHP的示例输出:

    <html><body>PGh0bWw+DQo8aGVhZD4NCjx0aXRsZT5IZWxsbzwvdGl0bGU+DQo8L2hlYWQ+DQo8Ym9keT4NCjxoMT5IZWxsbyBXb3JsZDwvaDE+DQo8L2JvZHk+DQo8L2h0bWw+</body></html>
    

    以下是来自Firebug的解码HTML(由GM脚本处理后):

    <html>
    <head>
    <title>Hello</title>
    </head>
    <body>
    <h1>Hello World</h1>
    </body>
    </html>
    

    这是解码PHP输出的GM脚本:

    function utf8_decode (str_data) {
        var tmp_arr = [],
            i = 0,
            ac = 0,
            c1 = 0,
            c2 = 0,
            c3 = 0;
    
        str_data += '';
    
        while (i < str_data.length) {
            c1 = str_data.charCodeAt(i);
            if (c1 < 128) {
                tmp_arr[ac++] = String.fromCharCode(c1);
                i++;
            } else if (c1 > 191 && c1 < 224) {
                c2 = str_data.charCodeAt(i + 1);
                tmp_arr[ac++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
                i += 2;
            } else {
                c2 = str_data.charCodeAt(i + 1);
                c3 = str_data.charCodeAt(i + 2);
                tmp_arr[ac++] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                i += 3;
            }
        }
    
        return tmp_arr.join('');
    }
    
    function base64_decode (data) {
        var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
        var o1, o2, o3, h1, h2, h3, h4, bits, i = 0,
            ac = 0,
            dec = "",
            tmp_arr = [];
    
        if (!data) {
            return data;
        }
    
        data += '';
    
        do { // unpack four hexets into three octets using index points in b64
            h1 = b64.indexOf(data.charAt(i++));
            h2 = b64.indexOf(data.charAt(i++));
            h3 = b64.indexOf(data.charAt(i++));
            h4 = b64.indexOf(data.charAt(i++));
    
            bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;
    
            o1 = bits >> 16 & 0xff;
            o2 = bits >> 8 & 0xff;
            o3 = bits & 0xff;
    
            if (h3 == 64) {
                tmp_arr[ac++] = String.fromCharCode(o1);
            } else if (h4 == 64) {
                tmp_arr[ac++] = String.fromCharCode(o1, o2);
            } else {
                tmp_arr[ac++] = String.fromCharCode(o1, o2, o3);
            }
        } while (i < data.length);
    
        dec = tmp_arr.join('');
        dec = utf8_decode(dec);
    
        return dec;
    }
    
    document.documentElement.innerHTML = base64_decode(document.body.innerHTML);
    

    我认为问题是我将解码后的HTML分配给 document.documentElement.innerHTML ,并且通过这样做将整个内容放在 body 元素中?

    所以问题是,从字符串重新创建HTML文档的正确方法是什么?

2 个答案:

答案 0 :(得分:1)

您称之为“复杂”页面的问题是它们具有非常特定的DOM事件。这些事件将在浏览器第一次读取行时触发,或者在某些“断点”(如“onload”)时触发。由于您对代码进行了模糊处理,然后在完全下载后对其进行解码,因此浏览器不会重新读取该页面以触发这些事件。也许,只是也许,您可以在页面加载后手动调用这些事件中的每个函数,但是如果(某些)浏览器会让您很难做到这一点,我不会感到惊讶,因为页面已经创建为{{ 1}}。除此之外,JS引擎甚至可能根本不会索引新代码。

答案 1 :(得分:1)

由于您只是基本的64位编码,并且@ Battle_707已经说过dom事件的问题,为什么不发送重定向到data url的页面。这样浏览器应该触发所有正确的事件。

但是说真的,只要获得证书并登上dyndns.com,基地64就不会给你带来额外的安全保障

修改

由于您提到转移到AES,如果您可以找到JS AES实现,您可以在此处使用我的建议并构建数据URL客户端并重定向到该。

function openPageFromString(html){
    location="data:text/html,"+encodeURIComponent(html);
}