Use synchronous crypto for sealed sender
This commit is contained in:
parent
d81aaf654f
commit
6cfb3c9867
2 changed files with 25 additions and 73 deletions
83
ts/Crypto.ts
83
ts/Crypto.ts
|
@ -4,6 +4,14 @@
|
||||||
import pProps from 'p-props';
|
import pProps from 'p-props';
|
||||||
import { chunk } from 'lodash';
|
import { chunk } from 'lodash';
|
||||||
|
|
||||||
|
import {
|
||||||
|
CipherType,
|
||||||
|
encrypt,
|
||||||
|
decrypt,
|
||||||
|
hash,
|
||||||
|
sign,
|
||||||
|
} from './util/synchronousCrypto';
|
||||||
|
|
||||||
export function typedArrayToArrayBuffer(typedArray: Uint8Array): ArrayBuffer {
|
export function typedArrayToArrayBuffer(typedArray: Uint8Array): ArrayBuffer {
|
||||||
const ab = new ArrayBuffer(typedArray.length);
|
const ab = new ArrayBuffer(typedArray.length);
|
||||||
// Create a new Uint8Array backed by the ArrayBuffer and copy all values from
|
// Create a new Uint8Array backed by the ArrayBuffer and copy all values from
|
||||||
|
@ -79,8 +87,8 @@ export async function deriveMasterKeyFromGroupV1(
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function computeHash(data: ArrayBuffer): Promise<string> {
|
export async function computeHash(data: ArrayBuffer): Promise<string> {
|
||||||
const hash = await crypto.subtle.digest({ name: 'SHA-512' }, data);
|
const digest = await crypto.subtle.digest({ name: 'SHA-512' }, data);
|
||||||
return arrayBufferToBase64(hash);
|
return arrayBufferToBase64(digest);
|
||||||
}
|
}
|
||||||
|
|
||||||
// High-level Operations
|
// High-level Operations
|
||||||
|
@ -331,21 +339,7 @@ export async function hmacSha256(
|
||||||
key: ArrayBuffer,
|
key: ArrayBuffer,
|
||||||
plaintext: ArrayBuffer
|
plaintext: ArrayBuffer
|
||||||
): Promise<ArrayBuffer> {
|
): Promise<ArrayBuffer> {
|
||||||
const algorithm: HmacImportParams = {
|
return sign(key, plaintext);
|
||||||
name: 'HMAC',
|
|
||||||
hash: 'SHA-256',
|
|
||||||
};
|
|
||||||
const extractable = false;
|
|
||||||
|
|
||||||
const cryptoKey = await window.crypto.subtle.importKey(
|
|
||||||
'raw',
|
|
||||||
key,
|
|
||||||
algorithm,
|
|
||||||
extractable,
|
|
||||||
['sign']
|
|
||||||
);
|
|
||||||
|
|
||||||
return window.crypto.subtle.sign(algorithm, cryptoKey, plaintext);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function _encryptAes256CbcPkcsPadding(
|
export async function _encryptAes256CbcPkcsPadding(
|
||||||
|
@ -405,32 +399,7 @@ export async function encryptAesCtr(
|
||||||
plaintext: ArrayBuffer,
|
plaintext: ArrayBuffer,
|
||||||
counter: ArrayBuffer
|
counter: ArrayBuffer
|
||||||
): Promise<ArrayBuffer> {
|
): Promise<ArrayBuffer> {
|
||||||
const extractable = false;
|
return encrypt(key, plaintext, counter, CipherType.AES256CTR);
|
||||||
const algorithm = {
|
|
||||||
name: 'AES-CTR',
|
|
||||||
counter: new Uint8Array(counter),
|
|
||||||
length: 128,
|
|
||||||
};
|
|
||||||
|
|
||||||
const cryptoKey = await crypto.subtle.importKey(
|
|
||||||
'raw',
|
|
||||||
key,
|
|
||||||
// `algorithm` appears to be an instance of AesCtrParams,
|
|
||||||
// which is not in the param's types, so we need to pass as `any`.
|
|
||||||
// TODO: just pass the string "AES-CTR", per the docs?
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
algorithm as any,
|
|
||||||
extractable,
|
|
||||||
['encrypt']
|
|
||||||
);
|
|
||||||
|
|
||||||
const ciphertext = await crypto.subtle.encrypt(
|
|
||||||
algorithm,
|
|
||||||
cryptoKey,
|
|
||||||
plaintext
|
|
||||||
);
|
|
||||||
|
|
||||||
return ciphertext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function decryptAesCtr(
|
export async function decryptAesCtr(
|
||||||
|
@ -438,31 +407,7 @@ export async function decryptAesCtr(
|
||||||
ciphertext: ArrayBuffer,
|
ciphertext: ArrayBuffer,
|
||||||
counter: ArrayBuffer
|
counter: ArrayBuffer
|
||||||
): Promise<ArrayBuffer> {
|
): Promise<ArrayBuffer> {
|
||||||
const extractable = false;
|
return decrypt(key, ciphertext, counter, CipherType.AES256CTR);
|
||||||
const algorithm = {
|
|
||||||
name: 'AES-CTR',
|
|
||||||
counter: new Uint8Array(counter),
|
|
||||||
length: 128,
|
|
||||||
};
|
|
||||||
|
|
||||||
const cryptoKey = await crypto.subtle.importKey(
|
|
||||||
'raw',
|
|
||||||
key,
|
|
||||||
// `algorithm` appears to be an instance of AesCtrParams,
|
|
||||||
// which is not in the param's types, so we need to pass as `any`.
|
|
||||||
// TODO: just pass the string "AES-CTR", per the docs?
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
algorithm as any,
|
|
||||||
extractable,
|
|
||||||
['decrypt']
|
|
||||||
);
|
|
||||||
const plaintext = await crypto.subtle.decrypt(
|
|
||||||
algorithm,
|
|
||||||
cryptoKey,
|
|
||||||
ciphertext
|
|
||||||
);
|
|
||||||
|
|
||||||
return plaintext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function encryptAesGcm(
|
export async function encryptAesGcm(
|
||||||
|
@ -526,7 +471,7 @@ export async function decryptAesGcm(
|
||||||
// Hashing
|
// Hashing
|
||||||
|
|
||||||
export async function sha256(data: ArrayBuffer): Promise<ArrayBuffer> {
|
export async function sha256(data: ArrayBuffer): Promise<ArrayBuffer> {
|
||||||
return crypto.subtle.digest('SHA-256', data);
|
return hash(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Utility
|
// Utility
|
||||||
|
|
|
@ -20,13 +20,19 @@ export function hash(data: ArrayBuffer): ArrayBuffer {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum CipherType {
|
||||||
|
AES256CBC = 'aes-256-cbc',
|
||||||
|
AES256CTR = 'aes-256-ctr',
|
||||||
|
}
|
||||||
|
|
||||||
export function encrypt(
|
export function encrypt(
|
||||||
key: ArrayBuffer,
|
key: ArrayBuffer,
|
||||||
data: ArrayBuffer,
|
data: ArrayBuffer,
|
||||||
iv: ArrayBuffer
|
iv: ArrayBuffer,
|
||||||
|
cipherType: CipherType = CipherType.AES256CBC
|
||||||
): ArrayBuffer {
|
): ArrayBuffer {
|
||||||
const cipher = crypto.createCipheriv(
|
const cipher = crypto.createCipheriv(
|
||||||
'aes-256-cbc',
|
cipherType,
|
||||||
Buffer.from(key),
|
Buffer.from(key),
|
||||||
Buffer.from(iv)
|
Buffer.from(iv)
|
||||||
);
|
);
|
||||||
|
@ -41,10 +47,11 @@ export function encrypt(
|
||||||
export function decrypt(
|
export function decrypt(
|
||||||
key: ArrayBuffer,
|
key: ArrayBuffer,
|
||||||
data: ArrayBuffer,
|
data: ArrayBuffer,
|
||||||
iv: ArrayBuffer
|
iv: ArrayBuffer,
|
||||||
|
cipherType: CipherType = CipherType.AES256CBC
|
||||||
): ArrayBuffer {
|
): ArrayBuffer {
|
||||||
const cipher = crypto.createDecipheriv(
|
const cipher = crypto.createDecipheriv(
|
||||||
'aes-256-cbc',
|
cipherType,
|
||||||
Buffer.from(key),
|
Buffer.from(key),
|
||||||
Buffer.from(iv)
|
Buffer.from(iv)
|
||||||
);
|
);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue