A client-side encryption/decryption tool for securely sharing content via GitHub Gists. All encryption and decryption happens in your browser - no data is sent to any server.
When someone visits a URL like:
https://austegard.com/pv.html?GIST_ID#key=YOUR_KEY
Here’s what happens:
iv and data fields)#key=...)Important: The key in the URL fragment (#key=...) is never sent to any server - it stays in the browser only. This is a fundamental feature of URL fragments.
If you prefer not to use pv.html, you can manually decrypt:
The tool supports programmatic encryption/decryption via the postMessage API, similar to the Claude Pruner tool.
// Open the tool in a hidden iframe or popup
const cryptoWindow = window.open('https://austegard.com/web-utilities/gist-encryption.html');
// Wait for it to load, then send encryption request
window.addEventListener('message', (event) => {
if (event.data.type === 'gist-encrypt-result') {
if (event.data.success) {
console.log('Key:', event.data.key);
console.log('Encrypted:', event.data.encrypted);
} else {
console.error('Encryption failed:', event.data.error);
}
}
});
cryptoWindow.postMessage({
type: 'gist-encrypt',
text: 'Your secret text here',
salt: 'optional metadata'
}, 'https://austegard.com');
window.addEventListener('message', (event) => {
if (event.data.type === 'gist-decrypt-result') {
if (event.data.success) {
console.log('Salt:', event.data.salt);
console.log('Decrypted text:', event.data.text);
} else {
console.error('Decryption failed:', event.data.error);
}
}
});
cryptoWindow.postMessage({
type: 'gist-decrypt',
key: 'YOUR_ENCRYPTION_KEY',
encrypted: {
salt: 'metadata',
iv: 'base64-encoded-iv',
data: 'base64-encoded-ciphertext'
}
}, 'https://austegard.com');
Encrypted content is stored as JSON:
{
"iv": "base64-encoded initialization vector",
"data": "base64-encoded encrypted content"
}
What is the IV? The Initialization Vector is a random 96-bit value that ensures the same plaintext encrypts to different ciphertext each time. It’s safe to store publicly alongside the encrypted data.
✅ Secure:
crypto.getRandomValues()⚠️ Important:
Visit: https://austegard.com/web-utilities/gist-encryption.html
Enter text: "My secret notes"
Click: Encrypt
Copy: Key and encrypted JSON
Visit: https://gist.github.com
Create new gist: paste encrypted JSON
Note the gist ID: a1902d995b5c6157a9eaf69afa355723
Share URL: https://austegard.com/pv.html?a1902d995b5c6157a9eaf69afa355723#key=Abc123...
The recipient clicks the link and sees the decrypted content automatically!
You can easily copy this tool to your own repository or use it locally. This is recommended if you don’t want to rely on austegard.com or want to customize the functionality.
web-utilities/gist-encryption.html (the encryption tool)pv.html (the gist viewer)scripts/htmlpreview.js (pv.html’s JavaScript with decryption support)git add web-utilities/gist-encryption.html pv.html scripts/htmlpreview.js
git commit -m "Add gist encryption tools"
git push
gist-encryption.html and change line 541:
// Change this:
const url = `https://austegard.com/pv.html?${gistId}#key=${encodeURIComponent(key)}`;
// To this (replace YOUR_USERNAME):
const url = `https://YOUR_USERNAME.github.io/pv.html?${gistId}#key=${encodeURIComponent(key)}`;
https://YOUR_USERNAME.github.io/web-utilities/gist-encryption.htmlhttps://YOUR_USERNAME.github.io/pv.htmlgist-encryption.html directly in your browser (file:// works fine)python -m http.server 8000http://localhost:8000/pv.html?GIST_ID#key=...Note: If using locally, you’ll need to manually update the URL in step 3 of the encryption tool to point to your local pv.html.
The files are completely standalone - no build process, no dependencies beyond a modern browser.
This tool was inspired by agentexport, which uses similar encryption techniques for sharing AI agent conversations.
Requires a modern browser with Web Crypto API support:
Part of the oaustegard.github.io project. See repository for license details.