Howto Make a simple Web-Chat E2E encryptet #682
-
Hi .... Thank you very much for this nice tool !! I'm running a piping-server self-hosted on my Rasperry and you the simple web-chat example for a simple 2 Person chat. I saw your E2E web-chat example, but it's not clear to me how to do by myself. Is a https piping server necessary for a E2E encryptet web-chat? If yes, how to create the certs for the Server? And how insert them to the html Page? If only encryption in the HTML Side is necessary how to insert in the simple Web chat example? My goal is: The connection allways goes to my Rasperry piping-server. It's not necessary to generate a new cert every usage, but how to insert the certs to the simple-web-chat example to get a encrypted connection between user1.html and user2.html? Please, can you give me some hints? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
Thanks! I haven't noticed this. |
Beta Was this translation helpful? Give feedback.
-
HintsI'd like give you some hints.
You may think Diffie–Hellman key exchange is like magic because it can exchage a common synmmetric key over an untrusted connection. This video may be help to understand its underlying math. Sample code of Diffie–Hellman key exchange in JavaScriptHere is a code which includes Elliptic curve Diffie–Hellman key exchange, encryption and decryption.
For simplicity, the whole code is in a single file without network access. (async () => {
// A creates a key pair
const aKeyPair = await window.crypto.subtle.generateKey(
{ name: 'ECDH', namedCurve: 'P-256'},
false,
['deriveKey', 'deriveBits']
);
// A exports a public key as JSON Web Key (this should be transferred to B over network usually)
const aPublicKeyJWK = await crypto.subtle.exportKey('jwk', aKeyPair.publicKey);
// B creates a key pair
const bKeyPair = await window.crypto.subtle.generateKey(
{ name: 'ECDH', namedCurve: 'P-256'},
false,
['deriveKey', 'deriveBits']
);
// B exports a public key as JSON Web Key (this should be transferred to A over network usually)
const bPublicKeyJWK = await crypto.subtle.exportKey('jwk', bKeyPair.publicKey);
// A imports B's public key
const bRemotePublicKey = await crypto.subtle.importKey(
'jwk',
bPublicKeyJWK,
{name: 'ECDH', namedCurve: 'P-256'},
false,
[]
);
// Generate initial vector for AES-GCM encryption (12 bytes is recommented)
// The iv can be transferred without encryption.
const iv = crypto.getRandomValues(new Uint8Array(12));
// A creates a common secret key using remote B's public key
const aKey = await crypto.subtle.deriveKey(
{ name: 'ECDH', public: bRemotePublicKey },
aKeyPair.privateKey,
{'name': 'AES-GCM', length: 128},
false,
['encrypt', 'decrypt']
);
// raw is a secret message to tell to B securely.
const raw = new Uint8Array([1, 2, 3]);
// A encrypts the secret message.
const encrypted = await crypto.subtle.encrypt(
{ name: 'AES-GCM', iv, tagLength: 128 },
aKey,
raw
);
// B imports A's public JSON Web Key.
const aRemotePublicKey = await crypto.subtle.importKey(
'jwk',
aPublicKeyJWK,
{ name: 'ECDH', namedCurve: 'P-256'},
false,
[]
);
// B creates the common secret key using remote A's public key
// This bKey should be the same as aKey.
const bKey = await crypto.subtle.deriveKey(
{ name: 'ECDH', public: aRemotePublicKey },
bKeyPair.privateKey,
{ name: 'AES-GCM', length: 128 },
false,
['encrypt', 'decrypt']
);
// B decrypts A's encrypted message.
const decrypted = await crypto.subtle.decrypt(
{ name: 'AES-GCM', iv, tagLength: 128 },
bKey,
encrypted
);
// Whether raw and decrypted are the same
console.log(JSON.stringify([...raw]) === JSON.stringify([...new Uint8Array(decrypted)]));
// => true
})(); |
Beta Was this translation helpful? Give feedback.
Hints
I'd like give you some hints.
You may think Diffie–Hellman key exchange is like magic because it …