I recently found out modern browsers include a JavaScript API for creating public/private keys for cryptography.
I used this as an opportunity to figure out how to run JavaScript in a Jupyter notebook cell, using the IPython.display.Javascript mechanism.
This mechanism allows you to execute JavaScript that will be used to render a cell. It includes a copy of jQuery and makes a element
variable available corresponding to the cell your code is running in. It also provides a IPython.notebook.kernel.execute()
method which can be used to execute Python code from JavaScript.
Here's what I came up with:
from IPython.display import Javascript, display
display(Javascript("""
function generateKey() {
window.crypto.subtle
.generateKey(
{
name: "RSA-OAEP",
modulusLength: 4096,
publicExponent: new Uint8Array([1, 0, 1]),
hash: "SHA-256",
},
true,
["encrypt", "decrypt"]
)
.then((keyPair) => {
crypto.subtle.exportKey("jwk", keyPair.privateKey).then((v) => {
element.find("textarea:first").val(JSON.stringify(v, null, 4));
IPython.notebook.kernel.execute(
"private_key = " + JSON.stringify(JSON.stringify(v, null, 4))
);
});
crypto.subtle.exportKey("jwk", keyPair.publicKey).then((v) => {
element.find("textarea:last").val(JSON.stringify(v, null, 4));
IPython.notebook.kernel.execute(
"public_key = " + JSON.stringify(JSON.stringify(v, null, 4))
);
});
});
}
element.append(`
<h2>Generate a public/private key in JavaScript</h2>
<p><button>Generate key</button></p>
<h3>Private key</h3>
<textarea style="width: 100%; height: 20em"></textarea>
<h3>Public key</h3>
<textarea style="width: 100%; height: 20em"></textarea>
`);
element.find("button").click(generateKey);
"""))
This works! I get a new cell in the document containing the HTML from that backtick string at the end of the JavaScript code. When I click the button it runs my generateKey
function which generates a new key, displays it in the two textareas and makes that key available to the Jupyter environment as the public_key
and private_key
variables. I can then use them in subsequent cells from Python like this:
import json
private = json.loads(private_key)
public = json.loads(public_key)
Created 2021-01-22T13:52:44-08:00 · Edit