Password
124 | 125 |138 | Sorry, but password protection only works over a secure connection. Please load this page via HTTPS. 139 |
140 |143 | Your web browser appears to be outdated. Please visit this page using a modern browser. 144 |
145 |├── CNAME ├── python ├── requirements.txt ├── README.md └── encrypt.py ├── favicon.ico ├── .gitignore ├── LICENSE-FAVICON.md ├── README.md ├── CONTRIBUTING.md ├── .github └── FUNDING.yml ├── LICENSE.md ├── PowerShell ├── README.md └── Encrypt-StaticHTML.ps1 ├── legacy ├── demopage-unencrypted.html ├── github.svg ├── js │ ├── pbkdf2.js │ ├── FileSaver.js │ └── aes.js ├── index.html ├── decryptTemplate.html └── demopage │ └── index.html ├── demopage-unencrypted.html ├── github.svg ├── js └── FileSaver.js ├── demopage └── index.html ├── decryptTemplate.html ├── index.html └── decryptTemplate-legacy.html /CNAME: -------------------------------------------------------------------------------- 1 | pagecrypt.maxlaumeister.com -------------------------------------------------------------------------------- /python/requirements.txt: -------------------------------------------------------------------------------- 1 | pycryptodome>3.10 2 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaxLaumeister/PageCrypt/HEAD/favicon.ico -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | output.html 2 | 3 | ###################### 4 | # OS generated files # 5 | ###################### 6 | 7 | .DS_Store 8 | .DS_Store? 9 | ._* 10 | .Spotlight-V100 11 | .Trashes 12 | ehthumbs.db 13 | Thumbs.db 14 | -------------------------------------------------------------------------------- /LICENSE-FAVICON.md: -------------------------------------------------------------------------------- 1 | License for favicon.ico: 2 | 3 | This favicon was generated using the following graphics from Twitter Twemoji: 4 | 5 | - Graphics Title: 1f512.svg 6 | - Graphics Author: Copyright 2020 Twitter, Inc and other contributors (https://github.com/twitter/twemoji) 7 | - Graphics Source: https://github.com/twitter/twemoji/blob/master/assets/svg/1f512.svg 8 | - Graphics License: CC-BY 4.0 (https://creativecommons.org/licenses/by/4.0/) 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## PageCrypt - Password Protect HTML ## 2 | 3 | ### Overview ### 4 | 5 | This tool lets you securely password-protect an HTML file. Unlike other password-protection tools, this tool: 6 | 7 | 1. Has no server-side components (this tool and its password-protected pages run entirely in javascript). 8 | 9 | 2. Uses strong encryption, so the password-protection cannot be bypassed. 10 | 11 | For details and to use the tool, please see the [Project Page](https://pagecrypt.maxlaumeister.com/). 12 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to PageCrypt 2 | 3 | Thank you for taking the time to contribute! 4 | 5 | There are no specific guidelines for contributing to this project, but I want to make it clear that contributions are always welcome! 6 | 7 | This project has already accepted the generous contributions of **Zoltán Gálli** and **Nial Francis**. For details, read [the PageCrypt FAQ](https://www.maxlaumeister.com/pagecrypt/). Hopefully, you're next! 8 | 9 | If you have any questions, please don't hesitate to open a GitHub issue or [email me](https://www.maxlaumeister.com/contact/) directly. 10 | -------------------------------------------------------------------------------- /python/README.md: -------------------------------------------------------------------------------- 1 | ## Command Line Interface with Python ## 2 | This tool securely password-protects HTML files from the command line using Python3. 3 | 4 | ### Usage ### 5 | Run: `pip3 install -r requirements.txt` 6 | Run: `python3 encrypt.py filename [passphrase]` 7 | The first, mandatory parameter is the name of the file you want to encrypt. 8 | It is also possible to give the passphrase as the second parameter. If there is 9 | no passphrase provided at start, the script will ask for it while running. 10 | 11 | ### Dependencies ### 12 | 1) Python3 and Pip3 13 | 2) [pycryptodome](https://pypi.org/project/pycryptodome/) for AES. (pycrypto is [deprecated](https://github.com/pycrypto/pycrypto/issues/275)) 14 | 3) Python version of [pbkdf2](https://pypi.org/project/pbkdf2/): `pip3 install pbkdf2` 15 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: ['https://www.maxlaumeister.com/tip/'] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2021 Maximillian Laumeister 2 | Copyright (c) 2021 Samuel Plumppu 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | -------------------------------------------------------------------------------- /PowerShell/README.md: -------------------------------------------------------------------------------- 1 | ## Command Line Interface for PowerShell ## 2 | 3 | This tool securely password-protects HTML files from the command line using PowerShell (written with v5 but will very likely work on lower versions and Core). It utilises .NET encryption libraries. 4 | 5 | This implementation will also support a number of cypher changes (eg. key size and hash iterations) which the template currently does not. 6 | 7 | ### Usage ### 8 | 9 | Add this script and the `decryptTemplate-legacy.html` template into the same directory. 10 | 11 | To encrypt a string of text: 12 | `.\Encrypt-StaticHTML.ps1 -Text '--text to encrypt--' -Password '--encryption password--'` 13 | 14 | To encrypt a file: 15 | `.\Encrypt-StaticHTML.ps1 -File example.html -Password '--encryption password--'` 16 | 17 | ### Parameters ### 18 | 19 | **Mandatory:** 20 | `Password` = key password 21 | `Text` = text to encrypt, or 22 | `File` = file to encrypt 23 | 24 | **Optional:** 25 | `Template` = Custom template location 26 | `OutFile` = Destination file 27 | `KeySize` = AES key size (default 32 bytes) 28 | `Iterations` = Hash iterations (default 100) 29 | 30 | ### Dependencies ### 31 | 32 | None on Windows. 33 | -------------------------------------------------------------------------------- /legacy/demopage-unencrypted.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 |You're looking at a web page that has just been decrypted by your browser using the password you supplied. This works with any HTML page, including pages which use CSS 29 | 32 |
33 | 34 |You're looking at a web page that has just been decrypted by your browser using the password you supplied. This works with any HTML page, including pages which use Unicode ⚡, CSS 29 | 32 |
33 | 34 |Password
124 | 125 |138 | Sorry, but password protection only works over a secure connection. Please load this page via HTTPS. 139 |
140 |143 | Your web browser appears to be outdated. Please visit this page using a modern browser. 144 |
145 |Password
124 | 125 |138 | Sorry, but password protection only works over a secure connection. Please load this page via HTTPS. 139 |
140 |143 | Your web browser appears to be outdated. Please visit this page using a modern browser. 144 |
145 |This is the LEGACY version of PageCrypt. It produces less strongly protected documents, but they work over insecure HTTP connections. For most use cases, use the latest version of PageCrypt.
140 |Live Demo (pssst... the live demo password is "hunter2")
141 |Step 1. Choose HTML file
145 |Step 2. Choose password 146 |
Passwords don't match, try again.
155 |Step 3. Protect!
156 |Done! Check your downloads!
157 |Step 4. Tip me?
158 |Suggested donation is $5 for personal use, or $10-20 for businesses. Honor system!
159 |DISCLAIMER
165 |THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
166 |>>6*(3-v)&63));if(l=t.charAt(64))for(;d.length%4;)d.push(l);return d.join("")},parse:function(d){var l=d.length,s=this._map,t=s.charAt(64);t&&(t=d.indexOf(t),-1!=t&&(l=t));for(var t=[],r=0,w=0;w<
15 | l;w++)if(w%4){var v=s.indexOf(d.charAt(w-1))<<2*(w%4),b=s.indexOf(d.charAt(w))>>>6-2*(w%4);t[r>>>2]|=(v|b)<<24-8*(r%4);r++}return p.create(t,r)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="}})();
16 | (function(u){function p(b,n,a,c,e,j,k){b=b+(n&a|~n&c)+e+k;return(b< This tool lets you securely password-protect an HTML file. Unlike other password-protection tools, this tool: All you need to do is choose an HTML file and a password, and your page will be password-protected. Live Demo (pssst... the live demo password is "hunter2") Step 1. Choose HTML file Step 2. Choose password
139 | Passwords don't match, try again. Step 3. Protect! Done! Check your downloads! Step 4. Tip me? Suggested donation is $5 for personal use, or $10-20 for businesses. Honor system! Due to browser limitations, PageCrypt protected pages only work if served over a secure HTTPS connection (or if the .html file is opened directly from disk). This is because of some technical stuff involving SubtleCrypto and Secure Contexts. To produce html files that work over insecure HTTP connections, please use the legacy version of PageCrypt, which produces larger, less strongly protected documents. The HTML gets encrypted using the password, so it is unreadable without the password. An attacker could extract the encrypted document, but it would be an unusable mess until they decrypt it, which can only be done with the original password. View the source code for this tool (in your browser and/or on GitHub) and you can see for yourself that the password never leaves your computer! Standard user/password prompts require you have some sort of privileged access to the server. With Apache for instance, you need to be able to add a .htaccess file to the directory you want to protect. Since this tool produces a standard HTML file, you can host it literally anywhere, even places that don't give you access to the server configuration. This means you can use this tool to password-protect files without using .htaccess! This tool only encrypts the HTML document itself. If you inline your CSS/JS, or if you convert your images to data uris, then they will be encrypted too. Otherwise they will just be linked. Since the HTML itself is encrypted though, a visitor without the password will not be able see the URLs of any of the linked resources. PageCrypt is designed specifically to encrypt HTML. To encrypt other file types, I recommend Easy Encryption Everywhere by Michael D. Nahas. This tool uses the SubtleCrypto JavaScript API for its encryption. First, an encryption key is derived from the password using PBKDF2 and a random salt with 100,000 rounds. Then the HTML is encrypted using AES256. See Samuel Plumppu's rewrite of PageCrypt, which includes CLI and NPM automation, and NodeJS API support. In addition, thanks to Zoltán Gálli for this tool's Python CLI, and thanks to Nial Francis for this tool's PowerShell CLI. Contributions welcome! Finally, see Brent Scott's R-wrapper for PageCrypt. From the project page: "It is very common for R users to knit Rmarkdown documents to HTML docs. This provides an easy way to PageCrypt those documents without leaving R." Project by Maximillian Laumeister. The source code and license are available on GitHub.
182 | DISCLAIMER THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Password Password Password>>2]&255}};d.BlockCipher=v.extend({cfg:v.cfg.extend({mode:b,padding:q}),reset:function(){v.reset.call(this);var a=this.cfg,b=a.iv,a=a.mode;if(this._xformMode==this._ENC_XFORM_MODE)var c=a.createEncryptor;else c=a.createDecryptor,this._minBufferSize=1;this._mode=c.call(a,
28 | this,b&&b.words)},_doProcessBlock:function(a,b){this._mode.processBlock(a,b)},_doFinalize:function(){var a=this.cfg.padding;if(this._xformMode==this._ENC_XFORM_MODE){a.pad(this._data,this.blockSize);var b=this._process(!0)}else b=this._process(!0),a.unpad(b);return b},blockSize:4});var n=d.CipherParams=l.extend({init:function(a){this.mixIn(a)},toString:function(a){return(a||this.formatter).stringify(this)}}),b=(p.format={}).OpenSSL={stringify:function(a){var b=a.ciphertext;a=a.salt;return(a?s.create([1398893684,
29 | 1701076831]).concat(a).concat(b):b).toString(r)},parse:function(a){a=r.parse(a);var b=a.words;if(1398893684==b[0]&&1701076831==b[1]){var c=s.create(b.slice(2,4));b.splice(0,4);a.sigBytes-=16}return n.create({ciphertext:a,salt:c})}},a=d.SerializableCipher=l.extend({cfg:l.extend({format:b}),encrypt:function(a,b,c,d){d=this.cfg.extend(d);var l=a.createEncryptor(c,d);b=l.finalize(b);l=l.cfg;return n.create({ciphertext:b,key:c,iv:l.iv,algorithm:a,mode:l.mode,padding:l.padding,blockSize:a.blockSize,formatter:d.format})},
30 | decrypt:function(a,b,c,d){d=this.cfg.extend(d);b=this._parse(b,d.format);return a.createDecryptor(c,d).finalize(b.ciphertext)},_parse:function(a,b){return"string"==typeof a?b.parse(a,this):a}}),p=(p.kdf={}).OpenSSL={execute:function(a,b,c,d){d||(d=s.random(8));a=w.create({keySize:b+c}).compute(a,d);c=s.create(a.words.slice(b),4*c);a.sigBytes=4*b;return n.create({key:a,iv:c,salt:d})}},c=d.PasswordBasedCipher=a.extend({cfg:a.cfg.extend({kdf:p}),encrypt:function(b,c,d,l){l=this.cfg.extend(l);d=l.kdf.execute(d,
31 | b.keySize,b.ivSize);l.iv=d.iv;b=a.encrypt.call(this,b,c,d.key,l);b.mixIn(d);return b},decrypt:function(b,c,d,l){l=this.cfg.extend(l);c=this._parse(c,l.format);d=l.kdf.execute(d,b.keySize,b.ivSize,c.salt);l.iv=d.iv;return a.decrypt.call(this,b,c,d.key,l)}})}();
32 | (function(){for(var u=CryptoJS,p=u.lib.BlockCipher,d=u.algo,l=[],s=[],t=[],r=[],w=[],v=[],b=[],x=[],q=[],n=[],a=[],c=0;256>c;c++)a[c]=128>c?c<<1:c<<1^283;for(var e=0,j=0,c=0;256>c;c++){var k=j^j<<1^j<<2^j<<3^j<<4,k=k>>>8^k&255^99;l[e]=k;s[k]=e;var z=a[e],F=a[z],G=a[F],y=257*a[k]^16843008*k;t[e]=y<<24|y>>>8;r[e]=y<<16|y>>>16;w[e]=y<<8|y>>>24;v[e]=y;y=16843009*G^65537*F^257*z^16843008*e;b[k]=y<<24|y>>>8;x[k]=y<<16|y>>>16;q[k]=y<<8|y>>>24;n[k]=y;e?(e=z^a[a[a[G^z]]],j^=a[a[j]]):e=j=1}var H=[0,1,2,4,8,
33 | 16,32,64,128,27,54],d=d.AES=p.extend({_doReset:function(){for(var a=this._key,c=a.words,d=a.sigBytes/4,a=4*((this._nRounds=d+6)+1),e=this._keySchedule=[],j=0;j>>24]<<24|l[k>>>16&255]<<16|l[k>>>8&255]<<8|l[k&255]):(k=k<<8|k>>>24,k=l[k>>>24]<<24|l[k>>>16&255]<<16|l[k>>>8&255]<<8|l[k&255],k^=H[j/d|0]<<24);e[j]=e[j-d]^k}c=this._invKeySchedule=[];for(d=0;dd||4>=j?k:b[l[k>>>24]]^x[l[k>>>16&255]]^q[l[k>>>
34 | 8&255]]^n[l[k&255]]},encryptBlock:function(a,b){this._doCryptBlock(a,b,this._keySchedule,t,r,w,v,l)},decryptBlock:function(a,c){var d=a[c+1];a[c+1]=a[c+3];a[c+3]=d;this._doCryptBlock(a,c,this._invKeySchedule,b,x,q,n,s);d=a[c+1];a[c+1]=a[c+3];a[c+3]=d},_doCryptBlock:function(a,b,c,d,e,j,l,f){for(var m=this._nRounds,g=a[b]^c[0],h=a[b+1]^c[1],k=a[b+2]^c[2],n=a[b+3]^c[3],p=4,r=1;r
126 |
PageCrypt - Password Protect HTML
127 |
129 |
132 | Instructions
137 |
156 | FAQ
158 | Why do the resulting password-protected HTML documents only work when served via HTTPS?
159 | How can this be secure if it's client-side? Can't people just bypass the password?
161 | How do I know you're not keeping track of passwords I enter into this tool?
163 | Why would I want to use this instead of a .htaccess user/password prompt?
165 | Does PageCrypt encrypt all the CSS/Javascript/Images or only the HTML itself?
168 | Can PageCrypt protect .pdf, .zip, or any other types of files?
170 | What sort of crypto do you use?
172 | Is there a way to automate this or use it as a software library?
174 |
179 | More Info
181 |