Last active
May 19, 2023 08:35
-
-
Save reosablo/d620ffaec1485116a7d5da2cd9226de5 to your computer and use it in GitHub Desktop.
Equivalent code set for Web Crypto API and `node-forge` module
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
| #!/usr/bin/env node | |
| // @ts-check | |
| /** | |
| * @file Decrypts data from stdin using a private key. | |
| * | |
| * @example | |
| * node decrypt-forge.mjs [private-key-path] < encrypted-data.txt | |
| * | |
| * The default private key path is "private-key.pem". | |
| * The stdin data is expected to be base64 encoded. | |
| * The decrypted data is written to stdout. | |
| */ | |
| import forge from "node-forge"; | |
| import { readFile } from "node:fs/promises"; | |
| import process from "node:process"; | |
| import { text } from "node:stream/consumers"; | |
| const [, , privateKeyPath = "private-key.pem"] = process.argv; | |
| const [data, privateKeyPem] = await Promise.all([ | |
| text(process.stdin) | |
| .then((input) => forge.util.decode64(input)), | |
| readFile(privateKeyPath, "utf8"), | |
| ]); | |
| const decrypted = forge.pki | |
| .privateKeyFromPem(privateKeyPem) | |
| .decrypt(data, "RSA-OAEP", { md: forge.md.sha512.create() }); | |
| process.stdout.write(decrypted); |
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
| #!/usr/bin/env node | |
| // @ts-check | |
| /** | |
| * @file Decrypts data from stdin using a private key. | |
| * | |
| * @example | |
| * node decrypt-web.mjs [private-key-path] < encrypted-data.txt | |
| * | |
| * The default private key path is "private-key.pem". | |
| * The stdin data is expected to be base64 encoded. | |
| * The decrypted data is written to stdout. | |
| */ | |
| import { Buffer } from "node:buffer"; | |
| import { webcrypto as crypto } from "node:crypto"; | |
| import { readFile } from "node:fs/promises"; | |
| import process from "node:process"; | |
| import { text } from "node:stream/consumers"; | |
| const [, , privateKeyPath = "private-key.pem"] = process.argv; | |
| const [data, privateKey] = await Promise.all([ | |
| text(process.stdin) | |
| .then((input) => Buffer.from(input, "base64")), | |
| readFile(privateKeyPath, "utf8") | |
| .then((pem) => { | |
| const encodedDer = pem.replace(/-+[\w ]+-+|\s/g, ""); | |
| const der = Buffer.from(encodedDer, "base64"); | |
| return crypto.subtle.importKey( | |
| "pkcs8", | |
| der, | |
| { name: "RSA-OAEP", hash: "SHA-512" }, | |
| true, | |
| ["decrypt"], | |
| ); | |
| }), | |
| ]); | |
| const decrypted = await crypto.subtle.decrypt( | |
| { name: "RSA-OAEP" }, | |
| privateKey, | |
| data, | |
| ); | |
| process.stdout.write(Buffer.from(decrypted).toString()); |
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
| #!/usr/bin/env node | |
| // @ts-check | |
| /** | |
| * @file Encrypts data from stdin using a public key. | |
| * | |
| * @example | |
| * node encrypt-forge.mjs [public-key-path] > encrypted-data.txt | |
| * | |
| * The default public key path is "public-key.pem". | |
| * The stdout data is base64 encoded. | |
| * The encrypted data is written to stdout. | |
| */ | |
| import forge from "node-forge"; | |
| import { readFile } from "node:fs/promises"; | |
| import process from "node:process"; | |
| import { text } from "node:stream/consumers"; | |
| const [, , publicKeyPath = "public-key.pem"] = process.argv; | |
| const [data, publicKeyPem] = await Promise.all([ | |
| process.stdin.isTTY ? Date() : text(process.stdin), | |
| readFile(publicKeyPath, "utf8"), | |
| ]); | |
| const encrypted = forge.pki | |
| .publicKeyFromPem(publicKeyPem) | |
| .encrypt(data, "RSA-OAEP", { md: forge.md.sha512.create() }); | |
| process.stdout.write(forge.util.encode64(encrypted)); |
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
| #!/usr/bin/env node | |
| // @ts-check | |
| /** | |
| * @file Encrypts data from stdin using a public key. | |
| * | |
| * @example | |
| * node encrypt-web.mjs [public-key-path] > encrypted-data.txt | |
| * | |
| * The default public key path is "public-key.pem". | |
| * The stdout data is base64 encoded. | |
| * The encrypted data is written to stdout. | |
| */ | |
| import { Buffer } from "node:buffer"; | |
| import { webcrypto as crypto } from "node:crypto"; | |
| import { readFile } from "node:fs/promises"; | |
| import process from "node:process"; | |
| import { buffer } from "node:stream/consumers"; | |
| const [, , publicKeyPath = "public-key.pem"] = process.argv; | |
| const [data, publicKey] = await Promise.all([ | |
| process.stdin.isTTY ? Buffer.from(Date()) : buffer(process.stdin), | |
| readFile(publicKeyPath, "utf8") | |
| .then((pem) => { | |
| const encodedDer = pem.replace(/-+[\w ]+-+|\s/g, ""); | |
| const der = Buffer.from(encodedDer, "base64"); | |
| return crypto.subtle.importKey( | |
| "spki", | |
| der, | |
| { name: "RSA-OAEP", hash: "SHA-512" }, | |
| true, | |
| ["encrypt"], | |
| ); | |
| }), | |
| ]); | |
| const encrypted = await crypto.subtle.encrypt( | |
| { name: "RSA-OAEP" }, | |
| publicKey, | |
| data, | |
| ); | |
| process.stdout.write(Buffer.from(encrypted).toString("base64")); |
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
| #!/usr/bin/env node | |
| // @ts-check | |
| /** | |
| * @file Generates a RSA-OAEP/SHA-512 key pair files. | |
| * | |
| * @example | |
| * node generate-key-pair-forge.mjs [public-key-path] [private-key-path] | |
| * | |
| * The default public key path is "public-key.pem". | |
| * The default private key path is "private-key.pem". | |
| */ | |
| import forge from "node-forge"; | |
| import { writeFile } from "node:fs/promises"; | |
| import process from "node:process"; | |
| const [ | |
| , | |
| , | |
| publicKeyPath = "public-key.pem", | |
| privateKeyPath = "private-key.pem", | |
| ] = process.argv; | |
| const { privateKey, publicKey } = forge.pki.rsa.generateKeyPair({ bits: 2048 }); | |
| const publicKeyPem = forge.pki.publicKeyToPem(publicKey); | |
| const rsaPrivateKey = forge.pki.privateKeyToAsn1(privateKey); | |
| const privateKeyInfo = forge.pki.wrapRsaPrivateKey(rsaPrivateKey); | |
| const privateKeyPem = forge.pki.privateKeyInfoToPem(privateKeyInfo); | |
| await Promise.all([ | |
| writeFile(publicKeyPath, publicKeyPem, "utf8"), | |
| writeFile(privateKeyPath, privateKeyPem, "utf8"), | |
| ]); |
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
| #!/usr/bin/env node | |
| // @ts-check | |
| /** | |
| * @file Generates a RSA-OAEP/SHA-512 key pair files. | |
| * | |
| * @example | |
| * node generate-key-pair-web.mjs [public-key-path] [private-key-path] | |
| * | |
| * The default public key path is "public-key.pem". | |
| * The default private key path is "private-key.pem". | |
| */ | |
| import { Buffer } from "node:buffer"; | |
| import { webcrypto as crypto } from "node:crypto"; | |
| import { writeFile } from "node:fs/promises"; | |
| import process from "node:process"; | |
| const [ | |
| , | |
| , | |
| publicKeyPath = "public-key.pem", | |
| privateKeyPath = "private-key.pem", | |
| ] = process.argv; | |
| const { privateKey, publicKey } = await crypto.subtle.generateKey( | |
| { | |
| name: "RSA-OAEP", | |
| modulusLength: 2048, | |
| publicExponent: new Uint8Array([1, 0, 1]), | |
| hash: "SHA-256", | |
| }, | |
| true, | |
| ["encrypt", "decrypt"], | |
| ); | |
| await Promise.all(/**@type {const}*/([ | |
| ["PRIVATE KEY", crypto.subtle.exportKey("pkcs8", privateKey), privateKeyPath], | |
| ["PUBLIC KEY", crypto.subtle.exportKey("spki", publicKey), publicKeyPath], | |
| ]).map(async ([type, derPromise, path]) => { | |
| const encodedDer = Buffer.from(await derPromise).toString("base64"); | |
| const pem = [ | |
| `-----BEGIN ${type}-----`, | |
| encodedDer.replace(/.{1,64}/g, "$&\n"), | |
| `-----END ${type}-----`, | |
| ].join("\n"); | |
| await writeFile(path, pem, "utf8"); | |
| })); |
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
Show hidden characters
| { | |
| "compilerOptions": { | |
| "target": "ESNext", | |
| "module": "ESNext", | |
| "strict": true | |
| } | |
| } |
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
| { | |
| "private": true, | |
| "description": "node-forge and Web Crypto API RSA-OAEP demo for Node.js", | |
| "license": "Unlicense", | |
| "scripts": { | |
| "demo-forge": "node -p \"crypto.randomUUID()\" | node encrypt-forge.mjs | node decrypt-forge.mjs", | |
| "demo-web": "node -p \"crypto.randomUUID()\" | node encrypt-web.mjs | node decrypt-web.mjs", | |
| "prepare-forge": "node generate-key-pair-forge.mjs", | |
| "prepare-web": "node generate-key-pair-web.mjs" | |
| }, | |
| "dependencies": { | |
| "node-forge": "^1.3.1" | |
| }, | |
| "devDependencies": { | |
| "@types/node-forge": "^1.3.2" | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment