mirror of https://github.com/dapr/quickstarts.git
WIP: Crypto quickstart for JS
Signed-off-by: ItalyPaleAle <43508+ItalyPaleAle@users.noreply.github.com>
This commit is contained in:
parent
7d140fee39
commit
e0799feeb9
|
|
@ -0,0 +1,5 @@
|
|||
##lint files
|
||||
*.cjs
|
||||
|
||||
##node modules
|
||||
node_modules
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
# Dapr cryptography (Dapr SDK)
|
||||
|
||||
In this quickstart, you'll create an application that encrypts, and then decrypts, data using the Dapr cryptography APIs (high-level). We will:
|
||||
|
||||
- Encrypt and then decrypt a short string, reading the result in-memory, in a Buffer
|
||||
- Encrypt and then decrypt a large file, storing the encrypted and decrypted data to files using Node.js streams
|
||||
|
||||
Visit the documentation to learn more about the [Cryptography building block](https://v1-11.docs.dapr.io/developing-applications/building-blocks/cryptography/) in Dapr.
|
||||
|
||||
> **Note:** This example uses the Dapr SDK. Using the Dapr SDK, which leverages gRPC internally, is **strongly** recommended when using the high-level cryptography APIs (to encrypt and decrypt messages).
|
||||
|
||||
This quickstart includes one application:
|
||||
|
||||
- Node.js application `crypto-quickstart`
|
||||
|
||||
### Run Node.js service with Dapr
|
||||
|
||||
1. Navigate into the folder with the source and install dependencies:
|
||||
|
||||
<!-- STEP
|
||||
name: Install Node dependencies
|
||||
-->
|
||||
|
||||
```bash
|
||||
cd ./crypto-quickstart
|
||||
npm ci
|
||||
```
|
||||
<!-- END_STEP -->
|
||||
|
||||
2. This sample requires a private RSA key and a 256-bit symmetric (AES) key. We will generate them using OpenSSL:
|
||||
|
||||
<!-- STEP
|
||||
name: Generate keys
|
||||
working_dir: crypto-quickstart
|
||||
expected_stdout_lines:
|
||||
expected_stderr_lines:
|
||||
-->
|
||||
|
||||
```bash
|
||||
mkdir -p keys
|
||||
# Generate a private RSA key, 4096-bit keys
|
||||
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -out keys/rsa-private-key.pem
|
||||
# Generate a 256-bit key for AES
|
||||
openssl rand -out keys/symmetric-key-256 32
|
||||
```
|
||||
|
||||
<!-- END_STEP -->
|
||||
|
||||
3. Run the Node.js service app with Dapr:
|
||||
|
||||
<!-- STEP
|
||||
name: Run Node publisher
|
||||
expected_stdout_lines:
|
||||
- "== APP == Saving Order: { orderId: '1' }"
|
||||
- "== APP == Getting Order: { orderId: '1' }"
|
||||
- "Exited App successfully"
|
||||
expected_stderr_lines:
|
||||
working_dir: ./crypto-quickstart
|
||||
output_match_mode: substring
|
||||
background: true
|
||||
sleep: 10
|
||||
-->
|
||||
|
||||
```bash
|
||||
dapr run --app-id crypto-quickstart --resources-path ../../../components/ -- npm start
|
||||
```
|
||||
|
||||
<!-- END_STEP -->
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
# Output files
|
||||
encrypted.out
|
||||
decrypted.out.jpg
|
||||
|
||||
# Generated keys
|
||||
keys/
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 617 KiB |
|
|
@ -0,0 +1,87 @@
|
|||
import { createReadStream, createWriteStream } from "node:fs";
|
||||
import { readFile, writeFile } from "node:fs/promises";
|
||||
import { pipeline } from "node:stream/promises";
|
||||
|
||||
import { DaprClient, CommunicationProtocolEnum } from "@dapr/dapr";
|
||||
|
||||
const daprHost = process.env.DAPR_HOST ?? "127.0.0.1";
|
||||
const daprPort = process.env.DAPR_GRPC_PORT ?? "50001";
|
||||
|
||||
const testFileName = "federico-di-dio-photography-Q4g0Q-eVVEg-unsplash.jpg";
|
||||
|
||||
async function start() {
|
||||
const client = new DaprClient({
|
||||
daprHost,
|
||||
daprPort,
|
||||
communicationProtocol: CommunicationProtocolEnum.GRPC,
|
||||
});
|
||||
|
||||
// Encrypt and decrypt a message from a buffer
|
||||
await encryptDecryptBuffer(client);
|
||||
|
||||
// Encrypt and decrypt a message using streams
|
||||
await encryptDecryptStream(client);
|
||||
}
|
||||
|
||||
async function encryptDecryptBuffer(client) {
|
||||
// Message to encrypt
|
||||
const plaintext = `The secret is "passw0rd"`
|
||||
|
||||
// First, encrypt the message
|
||||
console.log("== Encrypting message using buffers");
|
||||
|
||||
const ciphertext = await client.crypto.encrypt(plaintext, {
|
||||
componentName: "crypto-local",
|
||||
keyName: "my-rsa-key",
|
||||
keyWrapAlgorithm: "RSA",
|
||||
});
|
||||
|
||||
console.log("Encrypted the message, got", ciphertext.length, "bytes");
|
||||
|
||||
// Decrypt the message
|
||||
console.log("== Decrypting message using buffers");
|
||||
const decrypted = await client.crypto.decrypt(ciphertext, {
|
||||
componentName: "crypto-local",
|
||||
});
|
||||
|
||||
console.log("Decrypted the message, got", decrypted.length, "bytes");
|
||||
console.log(decrypted.toString("utf8"));
|
||||
|
||||
// The contents should be equal
|
||||
if (decrypted.toString("utf8") != plaintext) {
|
||||
throw new Error("Decrypted message does not match original message");
|
||||
}
|
||||
}
|
||||
|
||||
async function encryptDecryptStream(client) {
|
||||
// First, encrypt the message
|
||||
console.log("== Encrypting message using streams");
|
||||
console.log("Encrypting", testFileName, "to ciphertext.out");
|
||||
|
||||
await pipeline(
|
||||
createReadStream(testFileName),
|
||||
await client.crypto.encrypt({
|
||||
componentName: "crypto-local",
|
||||
keyName: "symmetric256",
|
||||
keyWrapAlgorithm: "A256KW",
|
||||
}),
|
||||
createWriteStream("ciphertext.out"),
|
||||
);
|
||||
|
||||
console.log("Encrypted the message to ciphertext.out");
|
||||
|
||||
// Decrypt the message
|
||||
console.log("== Decrypting message using streams");
|
||||
console.log("Encrypting ciphertext.out to plaintext.out");
|
||||
await pipeline(
|
||||
createReadStream("ciphertext.out"),
|
||||
await client.crypto.decrypt({
|
||||
componentName: "crypto-local",
|
||||
}),
|
||||
createWriteStream("plaintext.out.jpg"),
|
||||
);
|
||||
|
||||
console.log("Decrypted the message to plaintext.out.jpg");
|
||||
}
|
||||
|
||||
await start();
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"name": "crypto-quickstart",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"start": "node index.mjs",
|
||||
"start:dapr": "dapr run --app-id crypto-quickstart --dapr-grpc-port 50001 -- npm run start"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@dapr/dapr": "^3.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^8.42.0"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
include ../../../docker.mk
|
||||
include ../../../validate.mk
|
||||
|
||||
# Remove generated files
|
||||
.PHONY: clean
|
||||
clean:
|
||||
-rm -r crypto-quickstart/keys
|
||||
-rm crypto-quickstart/encrypted.out
|
||||
-rm crypto-quickstart/decrypted.out.jpg
|
||||
Loading…
Reference in New Issue