Skip to content

Instantly share code, notes, and snippets.

@epicfaace
Created August 4, 2020 19:34
Show Gist options
  • Save epicfaace/c1a4452401af14d35b60fe211f2c1559 to your computer and use it in GitHub Desktop.
Save epicfaace/c1a4452401af14d35b60fe211f2c1559 to your computer and use it in GitHub Desktop.
encrypting an entire github pages (mkdocs) website with staticrypt - replace MY_PASSWORD and "YOUR SITE NAME HERE"
name: Docs
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
name: Build docs
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: 14.x
- uses: actions/setup-python@v1
with:
python-version: 3.6
- run: npm i -g staticrypt
- run: pip install -r requirements.docs.txt
- run: mkdocs build
- run: |
mkdir -p build/site
rsync -r --exclude="*.html" site build
find ./site -type f -name "*.html" -exec staticrypt {} MY_PASSWORD -o ./build/{} -f docs/template.html \;
- name: Deploy to GitHub Pages
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: crazy-max/ghaction-github-pages@v1.4.0
with:
keep_history: true
target-branch: gh-pages
build_dir: build/site
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
<!doctype html>
<html class="staticrypt-html">
<head>
<meta charset="utf-8">
<title>Private Page</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- do not cache this page -->
<meta http-equiv="cache-control" content="max-age=0"/>
<meta http-equiv="cache-control" content="no-cache"/>
<meta http-equiv="expires" content="0"/>
<meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT"/>
<meta http-equiv="pragma" content="no-cache"/>
<style>
.staticrypt-hr {
margin-top: 20px;
margin-bottom: 20px;
border: 0;
border-top: 1px solid #eee;
}
.staticrypt-page {
width: 360px;
padding: 8% 0 0;
margin: auto;
box-sizing: border-box;
}
.staticrypt-form {
position: relative;
z-index: 1;
background: #FFFFFF;
max-width: 360px;
margin: 0 auto 100px;
padding: 45px;
text-align: center;
box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24);
}
.staticrypt-form input {
outline: 0;
background: #f2f2f2;
width: 100%;
border: 0;
margin: 0 0 15px;
padding: 15px;
box-sizing: border-box;
font-size: 14px;
}
.staticrypt-form .staticrypt-decrypt-button {
text-transform: uppercase;
outline: 0;
background: white;
width: 100%;
border: 0;
padding: 15px;
color: black;
font-size: 14px;
cursor: pointer;
border: 1px solid black;
}
.staticrypt-form .staticrypt-decrypt-button:hover {
background: #eee;
}
.staticrypt-html {
height: 100%;
}
.staticrypt-body {
margin-bottom: 1em;
background: white;
font-family: "Arial", sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.staticrypt-instructions {
margin-top: -1em;
margin-bottom: 1em;
}
.staticrypt-title {
font-size: 1.5em;
}
.staticrypt-footer {
position: fixed;
height: 20px;
font-size: 16px;
padding: 2px;
bottom: 0;
left: 0;
right: 0;
margin-bottom: 0;
}
.staticrypt-footer p {
margin: 2px;
text-align: center;
float: right;
}
.staticrypt-footer a {
text-decoration: none;
}
</style>
</head>
<body class="staticrypt-body">
{crypto_tag}
<script>
/**
* Decrypt a salted msg using a password.
* Inspired by https://github.com/adonespitogo
*/
var keySize = 256;
var iterations = 1000;
function decrypt (encryptedMsg, pass) {
var salt = CryptoJS.enc.Hex.parse(encryptedMsg.substr(0, 32));
var iv = CryptoJS.enc.Hex.parse(encryptedMsg.substr(32, 32))
var encrypted = encryptedMsg.substring(64);
var key = CryptoJS.PBKDF2(pass, salt, {
keySize: keySize/32,
iterations: iterations
});
var decrypted = CryptoJS.AES.decrypt(encrypted, key, {
iv: iv,
padding: CryptoJS.pad.Pkcs7,
mode: CryptoJS.mode.CBC
}).toString(CryptoJS.enc.Utf8);
return decrypted;
}
window.onload = function() {
var form = document.getElementById('staticrypt-form');
if (form) {
form.addEventListener('submit', function(e) {
e.preventDefault();
var passphrase = document.getElementById('staticrypt-password').value;
localStorage.setItem("passphrase", passphrase);
if (!decryptWithPassphrase(passphrase)) {
alert('Bad passphrase!');
return;
}
});
}
}
if (localStorage.getItem("passphrase")) {
if (!decryptWithPassphrase(localStorage.getItem("passphrase"))) {
localStorage.removeItem("passphrase");
}
}
function decryptWithPassphrase(passphrase) {
var encryptedMsg = '{encrypted}',
encryptedHMAC = encryptedMsg.substring(0, 64),
encryptedHTML = encryptedMsg.substring(64),
decryptedHMAC = CryptoJS.HmacSHA256(encryptedHTML, CryptoJS.SHA256(passphrase).toString()).toString();
if (decryptedHMAC !== encryptedHMAC) {
return false;
}
var plainHTML = decrypt(encryptedHTML, passphrase);
document.getElementsByTagName("html")[0].innerHTML = plainHTML;
return true;
}
</script>
<div class="staticrypt-page">
<div class="staticrypt-form">
<div class="staticrypt-instructions">
<img src="#" style="width: 100%" alt="Logo" />
<p class="staticrypt-title">YOUR SITE NAME HERE</p>
<p>🔒 Private Docs - please enter password to unlock</p>
</div>
<hr class="staticrypt-hr">
<form id="staticrypt-form" action="#" method="post">
<input id="staticrypt-password"
type="password"
name="password"
placeholder="passphrase"
autofocus/>
<input type="submit" class="staticrypt-decrypt-button" value="ENTER"/>
</form>
</div>
</div>
<footer class="staticrypt-footer">
<p class="pull-right">Created with <a href="https://robinmoisson.github.io/staticrypt">StatiCrypt</a></p>
</footer>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment