From f3b3580062f5b3cbd72c4692d52487d044f5a390 Mon Sep 17 00:00:00 2001 From: fwqaaq Date: Sun, 15 Dec 2024 22:20:20 -0800 Subject: [PATCH 1/3] Add Exampke: drive key with ecdh --- examples/scripts/ecdh_drive_key.ts | 123 +++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 examples/scripts/ecdh_drive_key.ts diff --git a/examples/scripts/ecdh_drive_key.ts b/examples/scripts/ecdh_drive_key.ts new file mode 100644 index 000000000..fdbac5abc --- /dev/null +++ b/examples/scripts/ecdh_drive_key.ts @@ -0,0 +1,123 @@ +/** + * @title ECDH Drive Key + * @difficulty intermediate + * @tags cli, web + * @run + * @group Cryptography + * + * This example demonstrates how to derive a shared secret key using the Elliptic Curve Diffie-Hellman (ECDH) algorithm. + */ + +const data = 'Hello, Deno 2.0!' +const encoder = new TextEncoder() +const decoder = new TextDecoder() + +// Drive symmetric keys from ECDH key pairs +async function driveSymmetricKey( + privateKey: CryptoKey, + publicKey: CryptoKey +): Promise { + return await crypto.subtle.deriveKey( + { + name: 'ECDH', + public: publicKey, + }, + privateKey, + { + name: 'AES-GCM', + length: 256, + }, + true, + ['encrypt', 'decrypt'] + ) +} + +// Encrypt and decrypt messages using AES-GCM +async function encryptMessage( + key: CryptoKey, + iv: Uint8Array, + data: string +): Promise { + const dataBuffer = encoder.encode(data) + return await crypto.subtle.encrypt( + { + name: 'AES-GCM', + iv, + }, + key, + dataBuffer + ) +} + +async function decryptMessage( + key: CryptoKey, + iv: Uint8Array, + data: ArrayBuffer +): Promise { + const decryptedData = await crypto.subtle.decrypt( + { + name: 'AES-GCM', + iv, + }, + key, + data + ) + return decoder.decode(decryptedData) +} + +// Display +async function getBase64Key(key: CryptoKey) { + const buffer = await crypto.subtle.exportKey('raw', key) + return btoa(String.fromCharCode(...new Uint8Array(buffer))) +} + +// Generate an ECDH key pair for Alice +const AliceKey = await crypto.subtle.generateKey( + { + name: 'ECDH', + hash: { name: 'SHA-256' }, + namedCurve: 'P-256', // Use the NIST P-256 curve, or P-384 or P-521 + }, + true, + ['deriveKey'] +) + +// Generate an ECDH key pair for Bob +const BobKey = await crypto.subtle.generateKey( + { + name: 'ECDH', + hash: { name: 'SHA-256' }, + namedCurve: 'P-256', // Use the NIST P-256 curve, or P-384 or P-521 + }, + true, + ['deriveKey'] +) + +// Drive symmetric keys for Alice +const AliceSymmetricKey = await driveSymmetricKey( + AliceKey.privateKey, + BobKey.publicKey +) + +// Output the derived symmetric key for Alice +console.log("Alice's symmetric key:", await getBase64Key(AliceSymmetricKey)) + +// Drive symmetric keys for Bob +const BobSymmetricKey = await driveSymmetricKey( + BobKey.privateKey, + AliceKey.publicKey +) + +// Output the derived symmetric key for Bob +console.log("Bob's symmetric key:", await getBase64Key(BobSymmetricKey)) + +// Generate a random initialization vector (IV) for AES-GCM +// The IV must be unique for each encryption operation but doesn't need to be secret. +const iv = crypto.getRandomValues(new Uint8Array(12)) // 12-byte IV for AES-GCM + +// Encrypt and decrypt a message using the derived symmetric keys +const encryptedData = await encryptMessage(AliceSymmetricKey, iv, data) +console.log('Encrypted Data:', new Uint8Array(encryptedData)) + +const decryptedText = await decryptMessage(BobSymmetricKey, iv, encryptedData) +console.log('Verification of Decrypted Text:', decryptedText === data) From 2adffec84109b7234047a6f72a892fc75df66662 Mon Sep 17 00:00:00 2001 From: fwqaaq Date: Sun, 15 Dec 2024 22:21:34 -0800 Subject: [PATCH 2/3] Format --- examples/scripts/ecdh_drive_key.ts | 82 +++++++++++++++--------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/examples/scripts/ecdh_drive_key.ts b/examples/scripts/ecdh_drive_key.ts index fdbac5abc..77f3f37b6 100644 --- a/examples/scripts/ecdh_drive_key.ts +++ b/examples/scripts/ecdh_drive_key.ts @@ -8,116 +8,116 @@ * This example demonstrates how to derive a shared secret key using the Elliptic Curve Diffie-Hellman (ECDH) algorithm. */ -const data = 'Hello, Deno 2.0!' -const encoder = new TextEncoder() -const decoder = new TextDecoder() +const data = "Hello, Deno 2.0!"; +const encoder = new TextEncoder(); +const decoder = new TextDecoder(); // Drive symmetric keys from ECDH key pairs async function driveSymmetricKey( privateKey: CryptoKey, - publicKey: CryptoKey + publicKey: CryptoKey, ): Promise { return await crypto.subtle.deriveKey( { - name: 'ECDH', + name: "ECDH", public: publicKey, }, privateKey, { - name: 'AES-GCM', + name: "AES-GCM", length: 256, }, true, - ['encrypt', 'decrypt'] - ) + ["encrypt", "decrypt"], + ); } // Encrypt and decrypt messages using AES-GCM async function encryptMessage( key: CryptoKey, iv: Uint8Array, - data: string + data: string, ): Promise { - const dataBuffer = encoder.encode(data) + const dataBuffer = encoder.encode(data); return await crypto.subtle.encrypt( { - name: 'AES-GCM', + name: "AES-GCM", iv, }, key, - dataBuffer - ) + dataBuffer, + ); } async function decryptMessage( key: CryptoKey, iv: Uint8Array, - data: ArrayBuffer + data: ArrayBuffer, ): Promise { const decryptedData = await crypto.subtle.decrypt( { - name: 'AES-GCM', + name: "AES-GCM", iv, }, key, - data - ) - return decoder.decode(decryptedData) + data, + ); + return decoder.decode(decryptedData); } // Display async function getBase64Key(key: CryptoKey) { - const buffer = await crypto.subtle.exportKey('raw', key) - return btoa(String.fromCharCode(...new Uint8Array(buffer))) + const buffer = await crypto.subtle.exportKey("raw", key); + return btoa(String.fromCharCode(...new Uint8Array(buffer))); } // Generate an ECDH key pair for Alice const AliceKey = await crypto.subtle.generateKey( { - name: 'ECDH', - hash: { name: 'SHA-256' }, - namedCurve: 'P-256', // Use the NIST P-256 curve, or P-384 or P-521 + name: "ECDH", + hash: { name: "SHA-256" }, + namedCurve: "P-256", // Use the NIST P-256 curve, or P-384 or P-521 }, true, - ['deriveKey'] -) + ["deriveKey"], +); // Generate an ECDH key pair for Bob const BobKey = await crypto.subtle.generateKey( { - name: 'ECDH', - hash: { name: 'SHA-256' }, - namedCurve: 'P-256', // Use the NIST P-256 curve, or P-384 or P-521 + name: "ECDH", + hash: { name: "SHA-256" }, + namedCurve: "P-256", // Use the NIST P-256 curve, or P-384 or P-521 }, true, - ['deriveKey'] -) + ["deriveKey"], +); // Drive symmetric keys for Alice const AliceSymmetricKey = await driveSymmetricKey( AliceKey.privateKey, - BobKey.publicKey -) + BobKey.publicKey, +); // Output the derived symmetric key for Alice -console.log("Alice's symmetric key:", await getBase64Key(AliceSymmetricKey)) +console.log("Alice's symmetric key:", await getBase64Key(AliceSymmetricKey)); // Drive symmetric keys for Bob const BobSymmetricKey = await driveSymmetricKey( BobKey.privateKey, - AliceKey.publicKey -) + AliceKey.publicKey, +); // Output the derived symmetric key for Bob -console.log("Bob's symmetric key:", await getBase64Key(BobSymmetricKey)) +console.log("Bob's symmetric key:", await getBase64Key(BobSymmetricKey)); // Generate a random initialization vector (IV) for AES-GCM // The IV must be unique for each encryption operation but doesn't need to be secret. -const iv = crypto.getRandomValues(new Uint8Array(12)) // 12-byte IV for AES-GCM +const iv = crypto.getRandomValues(new Uint8Array(12)); // 12-byte IV for AES-GCM // Encrypt and decrypt a message using the derived symmetric keys -const encryptedData = await encryptMessage(AliceSymmetricKey, iv, data) -console.log('Encrypted Data:', new Uint8Array(encryptedData)) +const encryptedData = await encryptMessage(AliceSymmetricKey, iv, data); +console.log("Encrypted Data:", new Uint8Array(encryptedData)); -const decryptedText = await decryptMessage(BobSymmetricKey, iv, encryptedData) -console.log('Verification of Decrypted Text:', decryptedText === data) +const decryptedText = await decryptMessage(BobSymmetricKey, iv, encryptedData); +console.log("Verification of Decrypted Text:", decryptedText === data); From bb6ea3ad972a3cf694daf81a4da919767dde1780 Mon Sep 17 00:00:00 2001 From: fwqaaq Date: Mon, 16 Dec 2024 10:20:20 -0800 Subject: [PATCH 3/3] Update examples/scripts/ecdh_drive_key.ts --- examples/scripts/ecdh_drive_key.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/scripts/ecdh_drive_key.ts b/examples/scripts/ecdh_drive_key.ts index 77f3f37b6..50104c5fb 100644 --- a/examples/scripts/ecdh_drive_key.ts +++ b/examples/scripts/ecdh_drive_key.ts @@ -65,7 +65,7 @@ async function decryptMessage( return decoder.decode(decryptedData); } -// Display +// Get a human-readable string async function getBase64Key(key: CryptoKey) { const buffer = await crypto.subtle.exportKey("raw", key); return btoa(String.fromCharCode(...new Uint8Array(buffer)));