Skip to content

Instantly share code, notes, and snippets.

@zmwangx
Created March 16, 2020 13:19
Show Gist options
  • Save zmwangx/eef99a2c6a57dbac38a6a8b8ca3a7870 to your computer and use it in GitHub Desktop.
Save zmwangx/eef99a2c6a57dbac38a6a8b8ca3a7870 to your computer and use it in GitHub Desktop.
AES-CTR encryption & decryption in JavaScript & Python (use this for obfuscation, think thrice about using this for security)
<body>
<script>
const base64ToUInt8Array = b64 =>
Uint8Array.from(window.atob(b64), c => c.charCodeAt(0));
const textToUInt8Array = s => new TextEncoder().encode(s);
const UInt8ArrayToString = u8 => String.fromCharCode.apply(null, u8);
const UInt8ArrayToBase64 = u8 => window.btoa(UInt8ArrayToString(u8));
(async () => {
const key = await window.crypto.subtle.importKey(
"raw",
base64ToUInt8Array("HT24EFLxzRYATTG4PwMstxuIc6cnfnr4VjIeSJc9SMQ="),
{
name: "AES-CTR"
},
false,
["encrypt", "decrypt"]
);
const encrypt = async data => {
const iv = window.crypto.getRandomValues(new Uint8Array(16));
const ciphertext = new Uint8Array(
await window.crypto.subtle.encrypt(
{
name: "AES-CTR",
counter: iv,
length: 128
},
key,
textToUInt8Array(JSON.stringify(data))
)
);
return {
n: UInt8ArrayToBase64(iv),
c: UInt8ArrayToBase64(ciphertext)
};
};
const decrypt = async data => {
const plaintext = UInt8ArrayToString(
new Uint8Array(
await window.crypto.subtle.decrypt(
{
name: "AES-CTR",
counter: base64ToUInt8Array(data.n),
length: 128
},
key,
base64ToUInt8Array(data.c)
)
)
);
return JSON.parse(plaintext);
};
console.log(
JSON.stringify(await encrypt({ "hello, world": "你好,世界" }))
);
console.log(
await decrypt({
n: "I4ERqN5NHthiGzzIybMIug==",
c:
"sXm4vJ805FJYksYj7J3OOstpwdf/gl9o7mmJ3uTAUVfK99dE4oSmuaLsLlR8P18nKh4="
})
);
})();
</script>
</body>
import base64
import json
import os
import secrets
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
def b64enc(s: bytes) -> str:
return base64.b64encode(s).decode("ascii")
b64dec = base64.b64decode
class CipherBox:
def __init__(self, key):
self.key = key
def encrypt(self, obj):
nonce = secrets.token_bytes(16)
ciphertext = self._encrypt(json.dumps(obj).encode("ascii"), nonce)
return {
"n": b64enc(nonce),
"c": b64enc(ciphertext),
}
def decrypt(self, obj):
nonce = b64dec(obj["n"])
ciphertext = b64dec(obj["c"])
return json.loads(self._decrypt(ciphertext, nonce))
def _encrypt(self, plaintext, nonce):
encryptor = Cipher(
algorithms.AES(self.key), modes.CTR(nonce), backend=default_backend()
).encryptor()
return encryptor.update(plaintext) + encryptor.finalize()
def _decrypt(self, ciphertext, nonce):
decryptor = Cipher(
algorithms.AES(self.key), modes.CTR(nonce), backend=default_backend()
).decryptor()
return decryptor.update(ciphertext) + decryptor.finalize()
box = CipherBox(b64dec("HT24EFLxzRYATTG4PwMstxuIc6cnfnr4VjIeSJc9SMQ="))
print(
box.decrypt(
{
"n": "NIKaC/URcTKNm2baTTmZ2Q==",
"c": "MHC0/VRNNE6xDgwJ+MH0GrQbAM5KwPMUCvvOhsA/SxrrHg==",
}
)
)
print(json.dumps(box.encrypt({"hello, world": "你好,世界"})))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment