Interoperabilty between Python cryptography and CryptoJS in JavaScript / Google Apps Script.
The implementation uses the Fernet AES standard with PBKDF2 key derivation. Essentially, it just matches parameters across langagues. While each script can encode and decode in a self-contained manner, the primary function is to be interoperable between Python, JavaScript, and Google Apps Script.
🔒 Primary Uses:
- 🔒 Encrypt in Python / Decrypt in JavaScript or GAS
- 🔒 Encrypt in JavaScript or GAS / Decrypt in Python
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/[email protected]/fernetBrowser.min.js"></script>
Python
pip install cryptography
JavaScript
npm install fernet
npm install crypto-js [dependency of fernet, but just in case]
JS Browser (Node not required!)
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/[email protected]/fernetBrowser.min.js"></script>
Google Apps Script
The following can be cut/paste into separate files in your script:
Python
# This is not a pip-installable package.
# You can just pull or cut/paste the code into your own script.
import pyGAScrypto as pgasc
# Demo Settings
password = "lazydog"
salt = "salt"
cleartext = "Hello World"
# Note: also accepts dictionaries and lists
# Script will convert to string if a dictionary or is detected.
# cleartext = {"hello":"world"} or cleartext = ["hello","world"] etc...
ciphertext = pgasc.encrypt(cleartext, password, salt)
print("Ciphertext: ",ciphertext)
decoded_cleartext = pgasc.decrypt(ciphertext, password, salt)
print("Decoded Cleartext: ",decoded_cleartext)
HTML
<!--Import required scripts-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js" integrity="sha512-E8QSvWZ0eCLGk4km3hxSsNmGWbLtSCSUcewDQPQWZF6pEU8GlT8a5fF32wOl1i8ftdMhssTrF/OhyGWwonTcXA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script type="text/javascript" src="https://jeffkitson-music.github.io/js/pygasc.min.js"></script>
<!--Your Code-->
<script>
pygascExample()
</script>
Google Apps Script
function gasExample(){
var cleartext = "Hello World"
// Note: also accepts objects - script will stringifiy if an object type is detected.
// cleartext = {"hello":"world"}
var password = "lazydog"
var salt = "salt"
var ciphertext = encrypt(myDict,password,salt)
Logger.log("Ciphertext:")
Logger.log(ciphertext)
var clear = decrypt(ciphertext,password,salt)
Logger.log("Decrypted Cleartext:")
Logger.log(clear)
}
Use in GAS in another project/import as a library
/*
Set up the script in it's own script/project file
Save it and copy the script id in the browser URL
Example: https://script.google.com/home/projects/<THIS IS THE SCRIPT ID>/edit
Create a second script/project
Click the + next to the Library and paste your script id into the dialog box
Name the library for use in this script. Example below.
*/
function libraryDEMO(){
// Setup same as above
// myLibrary used as example name for import.
var ciphertext = myLibrary.encrypt(myDict,password,salt)
// etc...
}
-
Zergatul in this thread on Stackoverflow. This thread helped me get the basic concepts in PyCrypto to transfer them over to cryptography.
-
Nguyễn Thành Nghĩa in this thread on Stackoverflow. This thread helped me to get the decryption right in GAS/JavaScript.
-
PM 2Ring in this thread on Stackoverflow. The final piece of the puzzle was adding the padding in Python cryptography to match CryptoJS. CryptoJS pads natively, and cryptograpy doesn't!
-
Amit Agarwal for always having so many free resources on Google Apps Script. So often when I'm making personal projects I'll search something he's almost always the first result. I've started commenting "Amit to the rescue...again!" in my code whenever I use one of his solutions. Thank you, Amit, for teaching this amateur to use Apps Script. I am forever grateful.