-
-
Save Kelin2025/02cb984fb5d4ec58389aa6cbffc0ec1a 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 hidden or 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 \; | |
- uses: actions/checkout@v2 | |
- name: Deploy to Netlify | |
if: github.event_name == 'push' && github.ref == 'refs/heads/master' | |
uses: nwtgck/[email protected] | |
with: | |
publish-dir: './build/site' | |
production-branch: master | |
github-token: ${{ secrets.GITHUB_TOKEN }} | |
deploy-message: "Deploy from GitHub Actions" | |
enable-pull-request-comment: false | |
enable-commit-comment: true | |
overwrites-pull-request-comment: true | |
env: | |
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} | |
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }} | |
timeout-minutes: 1 |
This file contains hidden or 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