February 20, 2024
Some lessons, like keeping footware dry, I fear my kids will never learn…
Some lessons, like keeping footware dry, I fear my kids will never learn…
I’m having some fun with the new Micro.blog premium feature, private notes. I’m trying to figure out what parts of my workflow I can move over 😄

Currently reading: When Your Child Hurts by Rachael Coakley 📚
Back to Boston Children’s with my daughter. Since the winter storm is upon us and the other patients canceled, I’m hoping the appointment will go a bit quicker than the scheduled five hours. Hopefully the snow isn’t too bad when we head out. ❄️
I found myself needing to encrypt a small string on Deno (and subsequently decrypt it later) for a small side project. I checked out a few websites with code samples. But those didn’t work/were out of date. So this is what worked for me:
Note: I am not a security expert and I don’t play one on TV. You shouldn’t trust anything important with random code you found on the internet. Seriously.
First we generate a key using the standard SubtleCrypto api that ships with Deno. Then export a JSON webkey and save it. I’m putting it in an environmental variable. Make sure it is safe and secure.
const key = await crypto.subtle.generateKey({ name: "AES-CBC", length: 128 },true,["encrypt", "decrypt"]);
const rawKey = JSON.stringify(await crypto.subtle.exportKey("jwk", key));
Here we take the JSON webkey from our environmental variable that we created in step one and import it. Then using the key along with some random bytes, the initialization vector iv, we encrypt the string. The last two lines deal with getting the encrypted string into a format to save. The iv needs to be random and unique per message but it doesn’t need to be secret. So we can prepend it to the encrypted message.
You could potentially take this one step further and get a hex string from the encrypted bytes and save that. But for my needs I stopped here and stored the comma separated string of numbers.
async function encryptMe(decrypted)
{
const _appSecret = JSON.parse(Deno.env.get("APP_SECRET"));
const iv = await crypto.getRandomValues(new Uint8Array(16));
const key = await crypto.subtle.importKey("jwk", _appSecret, "AES-CBC", true, ["encrypt", "decrypt"]);
const encrypted = await crypto.subtle.encrypt({name: "AES-CBC", iv}, key, new TextEncoder().encode(decrypted));
const encryptedBytes = new Uint8Array(encrypted);
return `${iv.toString()}|${encryptedBytes.toString()}`;
}
The next step is to decrypt a string we previously encrypted. After we make a key we will need to separate out the two parts of the passed in message. The first part specifies the iv that was used and the second stores the encrypted message. You can use the Uint8Array.from to re-create the Unit8Array. Then call the decrypt method from the key, use a text decoder and you have your decrypted message. Yay! 👏
async function decryptMe(encrypted)
{
const _appSecret = JSON.parse(Deno.env.get("APP_SECRET"));
const key = await crypto.subtle.importKey("jwk", _appSecret, "AES-CBC", true, ["encrypt", "decrypt"]);
const ivPart = encrypted.split('|')[0];
const encryptedPart = encrypted.split('|')[1];
const encryptedBytes = Uint8Array.from(encryptedPart.split(',').map(num => parseInt(num)));
const iv = Uint8Array.from(ivPart.split(',').map(num => parseInt(num)));
const decrypted = await crypto.subtle.decrypt({name: "AES-CBC", iv}, key, encryptedBytes);
const decryptedBytes = new Uint8Array(decrypted);
return new TextDecoder().decode(decryptedBytes);
}
This morning I accidentally used mint extract instead of vanilla extract in my berry crisp 🤦
I want to thank seventeen year old me for trying out Tai Chi. I want to thank all the versions of me that kept with it. There are few things that make me feel so at peace. I let the world pass me by and I simply move with the forms.
It’s been a hard and long week. My daughter’s knee injury had an unexpected prognosis and its been tough to wrap my head around it. She’ll be all right, it’s just that the path to get there is longer and the way forward is murky.
Family game night ❤️

My son and I have had friction homeschooling this year. So yesterday morning we spent two hours brainstorming what to do and when he was last really happy with school. Turns out he was happiest when he read all the time. So we’re adjusting and adding in his wonderful choices ❤️📚
