Comparing version 2.0.0 to 3.0.0
# Changelog for `pagecrypt` | ||
## 3.0.0 - 2021-04-24 | ||
### Features | ||
- Replace `node-forge` with the standard Web Crypto API - both in Node.js and in browsers. | ||
- This greatly improves performance, bundle size and security compared to `v1.x` and `v2.x`. | ||
- This allows using the same native code both for encryption in Node.js and decryption in the browser, simplifying the codebase. | ||
- `decrypt-template.html` file size reduced from `290 KB` to `10 KB` - (**96 % less boilerplate code**). This ensures the encrypted page will be the clear majority of the code shipped to the user. | ||
- PBKDF2 default iteration count increased from `1e5` to `2e6`, greatly improving security. | ||
### Fixes | ||
- Fix [#6](https://github.com/Greenheart/pagecrypt/issues/6): Replace `vite preview` with `sirv-cli` to fix upstream issue | ||
- Upgrade to Tailwind CSS 2.1.2 | ||
- Cleanup web/index.html to reduce unused characters | ||
- Update README with instructions for enabling `https` for localhost | ||
- Use stronger test password | ||
--- | ||
## 2.0.0 - 2021-04-23 | ||
@@ -11,2 +33,4 @@ | ||
--- | ||
## 1.2.0 - 2021-03-15 | ||
@@ -13,0 +37,0 @@ |
59
index.js
@@ -1,5 +0,5 @@ | ||
const forge = require('node-forge') | ||
const { subtle, getRandomValues } = require('crypto').webcrypto | ||
const { mkdir, readFile, writeFile } = require('fs/promises') | ||
const { resolve, dirname } = require('path') | ||
const { base64 } = require('rfc4648') | ||
@@ -15,23 +15,34 @@ const packageRootDir = dirname(__filename) | ||
*/ | ||
function getEncryptedPayload(content, password) { | ||
const salt = forge.random.getBytesSync(256) | ||
const key = forge.pkcs5.pbkdf2(password, salt, 1e5, 32) | ||
const iv = forge.random.getBytesSync(16) | ||
async function getEncryptedPayload(content, password) { | ||
const encoder = new TextEncoder() | ||
const salt = getRandomValues(new Uint8Array(32)) | ||
const baseKey = await subtle.importKey( | ||
'raw', | ||
encoder.encode(password), | ||
'PBKDF2', | ||
false, | ||
['deriveKey'], | ||
) | ||
const key = await subtle.deriveKey( | ||
{ name: 'PBKDF2', salt, iterations: 2e6, hash: 'SHA-256' }, | ||
baseKey, | ||
{ name: 'AES-GCM', length: 256 }, | ||
false, | ||
['encrypt'], | ||
) | ||
const cipher = forge.cipher.createCipher('AES-GCM', key) | ||
cipher.start({ iv }) | ||
cipher.update(forge.util.createBuffer(content)) | ||
cipher.finish() | ||
const iv = getRandomValues(new Uint8Array(16)) | ||
const ciphertext = new Uint8Array( | ||
await subtle.encrypt( | ||
{ name: 'AES-GCM', iv }, | ||
key, | ||
encoder.encode(content), | ||
), | ||
) | ||
const totalLength = salt.length + iv.length + ciphertext.length | ||
const data = new Uint8Array( | ||
Buffer.concat([salt, iv, ciphertext], totalLength), | ||
) | ||
const tag = cipher.mode.tag | ||
const encrypted = forge.util.createBuffer() | ||
encrypted.putBuffer(cipher.output) | ||
const encryptedBuffer = Buffer.from(encrypted.getBytes(), 'binary') | ||
return { | ||
iv: forge.util.encode64(iv), | ||
tag: forge.util.encode64(tag.getBytes()), | ||
salt: forge.util.encode64(salt), | ||
data: forge.util.encode64(encryptedBuffer.toString('binary')), | ||
} | ||
return base64.stringify(data) | ||
} | ||
@@ -75,6 +86,6 @@ | ||
const encryptedPayload = JSON.stringify( | ||
getEncryptedPayload(inputHTML, password), | ||
return templateHTML.replace( | ||
'/*{{ENCRYPTED_PAYLOAD}}*/""', | ||
`"${await getEncryptedPayload(inputHTML, password)}"`, | ||
) | ||
return templateHTML.replace('/*{{ENCRYPTED_PAYLOAD}}*/""', encryptedPayload) | ||
} | ||
@@ -81,0 +92,0 @@ |
{ | ||
"name": "pagecrypt", | ||
"version": "2.0.0", | ||
"description": "A CLI to add client-side password-protection for HTML files", | ||
"version": "3.0.0", | ||
"description": "Easily add client-side password-protection to your Single Page Applications and HTML files.", | ||
"main": "index.js", | ||
@@ -12,4 +12,8 @@ "scripts": { | ||
"postbuild": "rm -rf web/build/assets", | ||
"serve": "vite preview" | ||
"serve": "sirv web/build --http2 --key priv.pem --cert cert.pem" | ||
}, | ||
"engines": { | ||
"node": ">= 15.0.0" | ||
}, | ||
"engineStrict": true, | ||
"repository": { | ||
@@ -25,2 +29,3 @@ "type": "git", | ||
"keywords": [ | ||
"web-crypto", | ||
"encryption", | ||
@@ -30,2 +35,5 @@ "password", | ||
"password-protection", | ||
"cryptography", | ||
"pbkdf2", | ||
"aes", | ||
"cli", | ||
@@ -35,3 +43,3 @@ "commandline", | ||
"crypto", | ||
"hidden webpage" | ||
"encrypted webpage" | ||
], | ||
@@ -43,3 +51,3 @@ "bugs": { | ||
"dependencies": { | ||
"node-forge": "^0.10.0", | ||
"rfc4648": "^1.4.0", | ||
"yargs": "^16.2.0" | ||
@@ -49,5 +57,5 @@ }, | ||
"autoprefixer": "^10.2.5", | ||
"generate-password": "^1.6.0", | ||
"postcss": "^8.2.12", | ||
"tailwindcss": "^2.1.1", | ||
"sirv-cli": "^1.0.11", | ||
"tailwindcss": "^2.1.2", | ||
"vite": "^2.2.1", | ||
@@ -54,0 +62,0 @@ "vite-plugin-singlefile": "^0.5.1" |
@@ -1,11 +0,13 @@ | ||
# PageCrypt - Password Protected HTML Pages | ||
# PageCrypt - Password Protected Single Page Applications and HTML files | ||
> A CLI to add client-side password-protection for HTML files | ||
> Easily add client-side password-protection to your Single Page Applications and HTML files. | ||
Inspired by [MaxLaumeister/PageCrypt](https://github.com/MaxLaumeister/PageCrypt). Thanks for sharing an excellent starting point to create this CLI! | ||
Inspired by [MaxLaumeister/PageCrypt](https://github.com/MaxLaumeister/PageCrypt). Thanks for sharing an excellent starting point to create this tool! | ||
## Usage | ||
## Get started | ||
### CLI | ||
There are 3 different ways to use `pagecrypt`: | ||
### 1. CLI | ||
Encrypt a single HTML-file with one command: | ||
@@ -17,4 +19,6 @@ | ||
### Automate `pagecrypt` in your build process | ||
### 2. Automate `pagecrypt` in your build process | ||
This allows automated encrypted builds for single page applications | ||
```sh | ||
@@ -29,3 +33,3 @@ npm i -D pagecrypt | ||
"devDependencies": { | ||
"pagecrypt": "^1.2.0" | ||
"pagecrypt": "^3.0.0" | ||
}, | ||
@@ -39,5 +43,5 @@ "scripts": { | ||
### Node.js API | ||
### 3. Node.js API | ||
You can use `pagecrypt` in your Node.js scripts: | ||
You can also use `pagecrypt` in your Node.js scripts: | ||
@@ -86,2 +90,10 @@ #### `encrypt(inputFile: string, outputFile: string, password: string): Promise<void>` | ||
## Setup a local development environment | ||
1. Install Node.js >= 15.0.0 | ||
2. Run `npm install` in project root. | ||
3. Install and use [`mkcert`](https://github.com/FiloSottile/mkcert) to generate local certificates to enable HTTPS for the development server. For example `mkcert localhost 192.168.1.32` to generate a two files ending with `*.pem`. | ||
4. Update `vite.config.js` to load the generated `*.pem` files in the `https` section. | ||
5. To use `npm run serve`, also update to the correct `*.pem` filenames in the npm script. | ||
## Testing | ||
@@ -88,0 +100,0 @@ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
141
102
23018
+ Addedrfc4648@^1.4.0
+ Addedrfc4648@1.5.3(transitive)
- Removednode-forge@^0.10.0
- Removednode-forge@0.10.0(transitive)