-
-
Save emptymalei/559cea3b3c7f727748f80e9d37a29b2e 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"
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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/[email protected] | |
with: | |
keep_history: true | |
target-branch: gh-pages | |
build_dir: build/site | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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