Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F3352834
D7024.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
2 KB
Referenced Files
None
Subscribers
None
D7024.diff
View Options
diff --git a/web/media/aes-crypto-utils.js b/web/media/aes-crypto-utils.js
new file mode 100644
--- /dev/null
+++ b/web/media/aes-crypto-utils.js
@@ -0,0 +1,74 @@
+// @flow
+
+const KEY_SIZE = 32; // bytes
+const IV_LENGTH = 12; // bytes - unique Initialization Vector (nonce)
+const TAG_LENGTH = 16; // bytes - GCM auth tag
+
+async function generateKey(): Promise<Uint8Array> {
+ const algorithm = { name: 'AES-GCM', length: 256 };
+ const key = await crypto.subtle.generateKey(algorithm, true, [
+ 'encrypt',
+ 'decrypt',
+ ]);
+ const keyData = await crypto.subtle.exportKey('raw', key);
+ return new Uint8Array(keyData);
+}
+
+async function encrypt(
+ keyBytes: Uint8Array,
+ plaintext: Uint8Array,
+): Promise<Uint8Array> {
+ if (keyBytes.length !== KEY_SIZE) {
+ throw new Error('Invalid AES key size');
+ }
+
+ // we're creating the buffer now so we can avoid reallocating it later
+ const outputBuffer = new ArrayBuffer(
+ plaintext.length + IV_LENGTH + TAG_LENGTH,
+ );
+ const ivBytes = new Uint8Array(outputBuffer, 0, IV_LENGTH);
+ const iv = crypto.getRandomValues(ivBytes);
+
+ const algorithm = { name: 'AES-GCM', iv: iv, tagLength: TAG_LENGTH * 8 };
+ const key = await crypto.subtle.importKey('raw', keyBytes, 'AES-GCM', false, [
+ 'encrypt',
+ ]);
+ const ciphertextWithTag = await crypto.subtle.encrypt(
+ algorithm,
+ key,
+ plaintext,
+ );
+
+ const result = new Uint8Array(outputBuffer);
+ result.set(new Uint8Array(ciphertextWithTag), iv.length);
+ return result;
+}
+
+async function decrypt(
+ keyBytes: Uint8Array,
+ sealedData: Uint8Array,
+): Promise<Uint8Array> {
+ if (keyBytes.length !== KEY_SIZE) {
+ throw new Error('Invalid AES key size');
+ }
+ if (sealedData.length < IV_LENGTH + TAG_LENGTH) {
+ throw new Error('Invalid ciphertext size');
+ }
+
+ const iv = sealedData.subarray(0, IV_LENGTH);
+ const ciphertextWithTag = sealedData.subarray(IV_LENGTH);
+
+ const algorithm = { name: 'AES-GCM', iv, tagLength: TAG_LENGTH * 8 };
+ const key = await crypto.subtle.importKey('raw', keyBytes, 'AES-GCM', false, [
+ 'decrypt',
+ ]);
+
+ const plaintextBuffer = await crypto.subtle.decrypt(
+ algorithm,
+ key,
+ ciphertextWithTag,
+ );
+ return new Uint8Array(plaintextBuffer);
+}
+
+export { generateKey, encrypt, decrypt };
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Nov 24, 7:12 AM (20 h, 59 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2574455
Default Alt Text
D7024.diff (2 KB)
Attached To
Mode
D7024: [web] Implement AES encryption functions
Attached
Detach File
Event Timeline
Log In to Comment