Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update crypto.ts #4

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 130 additions & 24 deletions src/crypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,71 +30,126 @@ export async function generateRsaKeyPair(): Promise<GenerateRsaKeyPair> {
// keys are extractable.

// remove this
return { publicKey: {} as any, privateKey: {} as any };
const { publicKey, privateKey } = await webcrypto.subtle.generateKey(
{
name: "RSA-OAEP",
modulusLength: 2048,
publicExponent: new Uint8Array([1, 0, 1]),
hash: { name: "SHA-256" },
},
true,
["encrypt", "decrypt"]
);
return { publicKey, privateKey };
}

// Export a crypto public key to a base64 string format
export async function exportPubKey(key: webcrypto.CryptoKey): Promise<string> {
// TODO implement this function to return a base64 string version of a public key

// remove this
return "";
const exportedKey = await webcrypto.subtle.exportKey("spki", key);
return arrayBufferToBase64(exportedKey);
}

// Export a crypto private key to a base64 string format
export async function exportPrvKey(
key: webcrypto.CryptoKey | null
key: webcrypto.CryptoKey | null
): Promise<string | null> {
// TODO implement this function to return a base64 string version of a private key

// remove this
return "";
if (key === null) {
return null;
}
const exportedKey = await webcrypto.subtle.exportKey("pkcs8", key);
return arrayBufferToBase64(exportedKey);
}



// Import a base64 string public key to its native format
export async function importPubKey(
strKey: string
strKey: string
): Promise<webcrypto.CryptoKey> {
// TODO implement this function to go back from the result of the exportPubKey function to it's native crypto key object

// remove this
return {} as any;
const keyBuffer = base64ToArrayBuffer(strKey);
return await webcrypto.subtle.importKey(
"spki",
keyBuffer,
{
name: "RSA-OAEP",
hash: "SHA-256",
},
true,
["encrypt"]
);
}

// Import a base64 string private key to its native format
export async function importPrvKey(
strKey: string
strKey: string
): Promise<webcrypto.CryptoKey> {
// TODO implement this function to go back from the result of the exportPrvKey function to it's native crypto key object

// remove this
return {} as any;
const keyBuffer = base64ToArrayBuffer(strKey);
return await webcrypto.subtle.importKey(
"pkcs8",
keyBuffer,
{
name: "RSA-OAEP",
hash: "SHA-256",
},
true,
["decrypt"]
);
}

// Encrypt a message using an RSA public key
export async function rsaEncrypt(
b64Data: string,
strPublicKey: string
b64Data: string,
strPublicKey: string
): Promise<string> {
// TODO implement this function to encrypt a base64 encoded message with a public key
// tip: use the provided base64ToArrayBuffer function

// remove this
return "";
const data = base64ToArrayBuffer(b64Data);
const publicKey = await importPubKey(strPublicKey);
const encryptedData = await webcrypto.subtle.encrypt(
{
name: "RSA-OAEP",
},
publicKey,
data
);
return arrayBufferToBase64(encryptedData);
}

// Decrypts a message using an RSA private key
export async function rsaDecrypt(
data: string,
privateKey: webcrypto.CryptoKey
data: string,
privateKey: webcrypto.CryptoKey
): Promise<string> {
// TODO implement this function to decrypt a base64 encoded message with a private key
// tip: use the provided base64ToArrayBuffer function

// remove this
return "";
const encryptedData = base64ToArrayBuffer(data);
const decryptedData = await webcrypto.subtle.decrypt(
{
name: "RSA-OAEP",
},
privateKey,
encryptedData
);
return arrayBufferToBase64(decryptedData);
}


// ######################
// ### Symmetric keys ###
// ######################
Expand All @@ -106,45 +161,96 @@ export async function createRandomSymmetricKey(): Promise<webcrypto.CryptoKey> {
// keys are extractable.

// remove this
return {} as any;
const key = await crypto.subtle.generateKey(
{
name: "AES-CBC",
length: 256,
},
true,
["encrypt", "decrypt"]
);

return key;
}


// Export a crypto symmetric key to a base64 string format
export async function exportSymKey(key: webcrypto.CryptoKey): Promise<string> {
// TODO implement this function to return a base64 string version of a symmetric key

// remove this
return "";
const exportedKey = await webcrypto.subtle.exportKey("raw", key);
return arrayBufferToBase64(exportedKey);
}

// Import a base64 string format to its crypto native format
export async function importSymKey(
strKey: string
strKey: string
): Promise<webcrypto.CryptoKey> {
// TODO implement this function to go back from the result of the exportSymKey function to it's native crypto key object

// remove this
return {} as any;
const keyBuffer = base64ToArrayBuffer(strKey);
const key = await webcrypto.subtle.importKey(
"raw",
keyBuffer,
{
name: "AES-CBC",
length: 256,
},
true,
["encrypt", "decrypt"]
);
return key;
}

// Encrypt a message using a symmetric key
export async function symEncrypt(
key: webcrypto.CryptoKey,
data: string
key: webcrypto.CryptoKey,
data: string
): Promise<string> {
// TODO implement this function to encrypt a base64 encoded message with a public key
// tip: encode the data to a uin8array with TextEncoder

return "";
const dataUint8Array = new TextEncoder().encode(data);
const iv = crypto.getRandomValues(new Uint8Array(16));
const encryptedData = await webcrypto.subtle.encrypt(
{
name: "AES-CBC",
iv: iv,
},
key,
dataUint8Array
);
const concatenatedData = new Uint8Array([...iv, ...new Uint8Array(encryptedData)]);
const base64EncryptedData = arrayBufferToBase64(concatenatedData.buffer);
return base64EncryptedData;
}



// Decrypt a message using a symmetric key
export async function symDecrypt(
strKey: string,
encryptedData: string
strKey: string,
encryptedData: string
): Promise<string> {
// TODO implement this function to decrypt a base64 encoded message with a private key
// tip: use the provided base64ToArrayBuffer function and use TextDecode to go back to a string format

return "";
const key = await importSymKey(strKey);
const encryptedDataBuffer = base64ToArrayBuffer(encryptedData);
const iv = encryptedDataBuffer.slice(0, 16);
const decryptedDataBuffer = await webcrypto.subtle.decrypt(
{
name: "AES-CBC",
iv: iv,
},
key,
encryptedDataBuffer.slice(16)
);

// Convert the decrypted data to a UTF-8 string
const decryptedDataString = new TextDecoder().decode(decryptedDataBuffer);

return decryptedDataString;
}