2021-08-30 20:41:18 +10:00
|
|
|
import { IvSize } from './index';
|
2021-07-13 12:32:57 +10:00
|
|
|
|
|
|
|
|
declare global {
|
|
|
|
|
interface Window {
|
|
|
|
|
msCrypto?: Crypto;
|
|
|
|
|
}
|
|
|
|
|
interface Crypto {
|
|
|
|
|
webkitSubtle?: SubtleCrypto;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const crypto = window.crypto || window.msCrypto;
|
|
|
|
|
const subtle: SubtleCrypto = crypto.subtle || crypto.webkitSubtle;
|
|
|
|
|
|
|
|
|
|
const Algorithm = { name: 'AES-GCM', length: 128 };
|
|
|
|
|
|
|
|
|
|
if (subtle === undefined) {
|
|
|
|
|
throw new Error('Failed to load Subtle CryptoAPI');
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-14 16:31:11 +10:00
|
|
|
export async function encrypt(
|
|
|
|
|
iv: Buffer | Uint8Array,
|
2021-07-13 12:32:57 +10:00
|
|
|
key: Buffer,
|
|
|
|
|
clearText: Buffer
|
|
|
|
|
): Promise<Buffer> {
|
|
|
|
|
return subtle
|
|
|
|
|
.importKey('raw', key, Algorithm, false, ['encrypt'])
|
|
|
|
|
.then((cryptoKey) =>
|
|
|
|
|
subtle.encrypt({ iv, ...Algorithm }, cryptoKey, clearText)
|
|
|
|
|
)
|
|
|
|
|
.then(Buffer.from);
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-14 16:31:11 +10:00
|
|
|
export async function decrypt(
|
2021-07-13 12:32:57 +10:00
|
|
|
iv: Buffer,
|
|
|
|
|
key: Buffer,
|
|
|
|
|
cipherText: Buffer
|
|
|
|
|
): Promise<Buffer> {
|
|
|
|
|
return subtle
|
|
|
|
|
.importKey('raw', key, Algorithm, false, ['decrypt'])
|
|
|
|
|
.then((cryptoKey) =>
|
2021-07-14 16:31:11 +10:00
|
|
|
subtle.decrypt({ iv, ...Algorithm }, cryptoKey, cipherText)
|
2021-07-13 12:32:57 +10:00
|
|
|
)
|
|
|
|
|
.then(Buffer.from);
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-14 16:31:11 +10:00
|
|
|
export function generateIv(): Uint8Array {
|
|
|
|
|
const iv = new Uint8Array(IvSize);
|
|
|
|
|
crypto.getRandomValues(iv);
|
|
|
|
|
return iv;
|
2021-07-13 12:32:57 +10:00
|
|
|
}
|