Skip to content

Instantly share code, notes, and snippets.

@andres-erbsen
Created October 23, 2011 18:24
Show Gist options
  • Save andres-erbsen/1307675 to your computer and use it in GitHub Desktop.
Save andres-erbsen/1307675 to your computer and use it in GitHub Desktop.
Python to javascript encryption - HTML is encrypted using AES and put in a JS string, decrypted on page load after getting password from user
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
from sys import stdin, stdout, stderr
from optparse import OptionParser
from os import urandom
from hashlib import sha256
from Crypto.Cipher import AES
from base64 import b64encode
DECRYPTOR = """<HTML
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>$title</title>
<style type="text/css">
html {overflow: auto;}
html, body, div, iframe {margin: 0px; padding: 0px; height: 100%; border: none;}
iframe {display: block; width: 100%; border: none; overflow-y: auto; overflow-x: hidden;}
</style>
</head>
<body>
<iframe id="magicframe" name="magicframe" src="about:blank" frameborder="0" marginheight="0" marginwidth="0" width="100%" height="100%" scrolling="auto"></iframe>
</body>
<script type="text/javascript" src="http://crypto-js.googlecode.com/files/2.0.0-crypto-sha1-hmac-pbkdf2-ofb-aes.js"></script>
<script type="text/javascript" src="http://crypto-js.googlecode.com/files/2.0.0-sha256-min.js"></script>
<script type="text/javascript">
var crypted = "$encryptedhtml"
var password = prompt("$message", "")
var key = Crypto.SHA256(password, { asBytes: true });
var plain = Crypto.AES.decrypt(crypted, key);
var iframe = document.getElementById("magicframe");
var iframedoc = iframe.document;
if (iframe.contentDocument)
iframedoc = iframe.contentDocument;
else if (iframe.contentWindow)
iframedoc = iframe.contentWindow.document;
if (iframe) {
iframedoc.open();
iframedoc.writeln(plain);
iframedoc.close();
} else {
document.open('text/html');
document.write(plain);
document.close();
}
</script>
</html>
"""
def wrap_to_jsdecrypter(encryptedhtml,replacements):
package = DECRYPTOR
for key in replacements:
package = package.replace('$'+key,replacements[key])
return package
def encrypt(plain,password):
key = sha256(password).digest()
padded = plain+(16 - len(plain)%16) * chr(0)
iv = urandom(16)
mode = AES.MODE_OFB
encryptor = AES.new(key, mode,iv)
cryptedbytes = encryptor.encrypt(padded)
return b64encode(iv + cryptedbytes)
def main():
parser = OptionParser()
parser.add_option('--password', '-p', default=None)
parser.add_option('--message', '-m', default="Enter password:")
parser.add_option('--title', default="")
parser.add_option('--text', '-t', action="store_false", dest="htmlinput", default=True,
help="Treat input as plaintext instead of HTML")
opts, args = parser.parse_args()
if not opts.password:
stderr.write("ERROR: No password specified."+'\n')
exit(-1)
rawtext = stdin.read()
if not opts.htmlinput:
rawtext = '<html><head></head><body><p>' + rawtext.replace('\n','<br/>') + '</p></body></html>'
ciphertext = encrypt(rawtext,opts.password)
replacements = dict(
encryptedhtml = ciphertext,
title = opts.title,
message = opts.message)
package = wrap_to_jsdecrypter(ciphertext,replacements)
stdout.write(package)
return 0
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment