Created
March 16, 2020 13:19
-
-
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)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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