chamesu
Version:
This package contains all packages of the chat application.
116 lines (88 loc) • 3.85 kB
text/typescript
/*
* Copyright (c) 2022.
* Author Peter Placzek (tada5hi)
* For the full copyright and license information,
* view the LICENSE file that was distributed with this source code.
*/
import {box, BoxKeyPair, randomBytes, secretbox} from "tweetnacl";
import {decodeBase64, decodeUTF8, encodeBase64, encodeUTF8} from 'tweetnacl-util';
/*
Public Key Encryption
*/
export function createPublicEncryptionNonce() : Uint8Array {
return randomBytes(box.nonceLength);
}
export function createPublicEncryptionKeyPair() : Record<'privateKey' | 'publicKey', string> {
const keyPair : BoxKeyPair = box.keyPair();
return {
privateKey: encodeBase64(keyPair.secretKey),
publicKey: encodeBase64(keyPair.publicKey)
}
}
export function createPublicEncryptionKeyPairFromPrivateKey(privateKey: string) : Record<'privateKey' | 'publicKey', string> {
const privateKeyUint8 : Uint8Array = decodeUTF8(privateKey);
const keyPair : BoxKeyPair = box.keyPair.fromSecretKey(privateKeyUint8);
return {
privateKey: encodeBase64(keyPair.secretKey),
publicKey: encodeBase64(keyPair.publicKey)
}
}
export function encryptPublicEncryptionMessage(message: string, publicKey: string, privateKey: string) : string {
const nonce = createPublicEncryptionNonce();
const messageUint8 : Uint8Array = decodeUTF8(message);
const publicKeyUint8 : Uint8Array = decodeBase64(publicKey);
const privateKeyKeyUint8 : Uint8Array = decodeBase64(privateKey);
const encrypted = box(messageUint8, nonce, publicKeyUint8, privateKeyKeyUint8);
const combined : Uint8Array = new Uint8Array(nonce.length + encrypted.length);
combined.set(nonce);
combined.set(encrypted, nonce.length);
return encodeBase64(combined);
}
export function decryptPublicEncryptionMessage(messageWithNonce: string, publicKey: string, privateKey: string) : string {
const messageWithNonceAsUint8Array = decodeBase64(messageWithNonce);
const nonce = messageWithNonceAsUint8Array.slice(0, box.nonceLength);
const message = messageWithNonceAsUint8Array.slice(
box.nonceLength,
messageWithNonce.length
);
const publicKeyUint8 : Uint8Array = decodeBase64(publicKey);
const privateKeyKeyUint8 : Uint8Array = decodeBase64(privateKey);
const decrypted : Uint8Array | null = box.open(message, nonce, publicKeyUint8, privateKeyKeyUint8);
if(!decrypted) {
throw new Error('Could not decrypt message...');
}
return encodeUTF8(decrypted);
}
/*
Secret Key Encryption
*/
export function createSymmetricEncryptionNonce() : Uint8Array {
return randomBytes(secretbox.nonceLength);
}
export function createSymmetricEncryptionKey() : string {
return encodeBase64(randomBytes(secretbox.keyLength))
}
export function encryptMessageSymmetric(message: string, secretKey: string) {
const keyUint8Array = decodeBase64(secretKey);
const nonce = createSymmetricEncryptionNonce();
const messageUint8 = decodeUTF8(message);
const out = secretbox(messageUint8, nonce, keyUint8Array);
const combined = new Uint8Array(nonce.length + out.length);
combined.set(nonce);
combined.set(out, nonce.length);
return encodeBase64(combined);
}
export function decryptMessageSymmetric(messageWithNonce: string, secretKey: string) {
const keyUint8Array = decodeBase64(secretKey);
const messageWithNonceAsUint8Array = decodeBase64(messageWithNonce);
const nonce = messageWithNonceAsUint8Array.slice(0, secretbox.nonceLength);
const message = messageWithNonceAsUint8Array.slice(
secretbox.nonceLength,
messageWithNonce.length
);
const decrypted = secretbox.open(message, nonce, keyUint8Array);
if (!decrypted) {
throw new Error("Could not decrypt message");
}
return encodeUTF8(decrypted);
}