diff options
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static/crypto.js')
| -rw-r--r-- | packages/meshbay-hub/src/meshbay_hub/static/crypto.js | 57 |
1 files changed, 4 insertions, 53 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/crypto.js b/packages/meshbay-hub/src/meshbay_hub/static/crypto.js index a3680ce..b74732c 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/crypto.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/crypto.js @@ -1,20 +1,12 @@ /** - * MeshBay Browser Crypto — AES-256-GCM private group decryption. - * Uses WebCrypto SubtleCrypto API (available in all modern browsers). - * - * Handles groups with cipher="aes-256-gcm" (browser-accessible groups). - * ChaCha20-Poly1305 groups (cipher="chacha20-poly1305") require the - * native client (node) for decryption — not supported in browser. + * MeshBay Browser Crypto — AES-256-GCM, through WebCrypto's SubtleCrypto API. + * The one content cipher, for every client (meshbay_common/webcrypto.py). * * Usage: * const gek = await importGEK(gekB64); * const plaintext = await decryptChunkBin(gek, fileHashHex, chunkIndex, nonce, ct); */ -const CIPHER_INFO_PREFIX = new TextEncoder().encode('file:'); -const CIPHER_INFO_SUFFIX_AES = new TextEncoder().encode(':aes'); - - // ── Key derivation ──────────────────────────────────────────────────────────── /** @@ -284,38 +276,7 @@ async function verifyChatSignature(deviceRaw, groupId, epoch, nonce, ct, sig) { } -// ── GEK generation + ECIES wrapping ────────────────────────────────────────── - -function generateGEK() { - return crypto.getRandomValues(new Uint8Array(32)); -} - -async function wrapGEK(gek, pkXRaw) { - const skEph = await crypto.subtle.generateKey({ name: 'X25519' }, true, ['deriveBits']); - const pkEphRaw = new Uint8Array(await crypto.subtle.exportKey('raw', skEph.publicKey)); - - const pkRecip = await crypto.subtle.importKey('raw', pkXRaw, { name: 'X25519' }, false, []); - const sharedBits = await crypto.subtle.deriveBits( - { name: 'X25519', public: pkRecip }, skEph.privateKey, 256); - - const sharedKey = await crypto.subtle.importKey( - 'raw', sharedBits, 'HKDF', false, ['deriveKey']); - const wrapKey = await crypto.subtle.deriveKey( - { name: 'HKDF', hash: 'SHA-256', salt: pkEphRaw, - info: new TextEncoder().encode('meshbay:gek_wrap:v1:aes') }, - sharedKey, - { name: 'AES-GCM', length: 256 }, false, ['encrypt']); - - const nonce = crypto.getRandomValues(new Uint8Array(12)); - const ct = await crypto.subtle.encrypt( - { name: 'AES-GCM', iv: nonce, additionalData: pkXRaw }, wrapKey, gek); - - return { - pk_eph_b64: btoa(String.fromCharCode(...pkEphRaw)), - nonce_b64: btoa(String.fromCharCode(...nonce)), - wrapped_b64: btoa(String.fromCharCode(...new Uint8Array(ct))), - }; -} +// ── GEK unwrapping (ECIES) ───────────────────────────────────────────────────── async function unwrapGEK(bundle, skXPkcs8, pkXRaw) { const pkEphRaw = b64decode(bundle.pk_eph_b64); @@ -342,16 +303,6 @@ async function unwrapGEK(bundle, skXPkcs8, pkXRaw) { return new Uint8Array(plain); } -// ── Chunk encryption (for upload) ──────────────────────────────────────────── - -async function encryptChunk(gek, fileHashHex, chunkIndex, plaintext) { - const chunkKey = await deriveChunkKey(gek, fileHashHex, chunkIndex); - const nonce = crypto.getRandomValues(new Uint8Array(12)); - const ct = await crypto.subtle.encrypt( - { name: 'AES-GCM', iv: nonce }, chunkKey, plaintext); - return { nonce, ct: new Uint8Array(ct) }; -} - function b64encode(bytes) { return btoa(String.fromCharCode(...bytes)); } @@ -583,7 +534,7 @@ async function verifyNodeSignature(nodePkB64, sigB64, transcript) { window.MeshBayCrypto = { importGEK, deriveChunkKey, decryptChunkBin, openGroup, sealGroup, - generateGEK, wrapGEK, unwrapGEK, encryptChunk, b64encode, b64decode, + unwrapGEK, b64encode, b64decode, adminTranscript, handshakeTranscript, handshakeProof, webrtcBinding, challengeTranscript, joinTranscript, verifyNodeSignature, constantTimeEqual, deviceRequestTranscript, deviceAddTranscript, deviceHelloTranscript, |