diff --git a/README.md b/README.md index aba508b..317cfdf 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ const decoded = base64Decode(encoded); // Restored. ```ts const file = await Deno.readFile("/path/to/binary.bin"); +const random = await cryptoRandom(16); // random byte array. const hash = await cryptoHash(true, file); // byte array of SHA2 512 bits hash value. const keyEcdh = await cryptoGenerateKey(true); // public/private key pair for ECDH, each in byte array. const keyEcdsa = await cryptoGenerateKey(false); // public/private key pair for ECDSA, each in byte array. @@ -120,6 +121,19 @@ The actual binary structure looks like this: This is for one file and repeats for the number of files. +# Browser Compatible +Some methods and classes in this module don't use `globalThis.Deno` internally and are browser compatible. + +I have prepared browser compatible code only export as [mod.compatible.ts](./mod.compatible.ts). + +By bundling this, you can easily create universal utility scripts. + +```sh +deno bundle https://deno.land/x/simple_utility@(version)/mod.compatible.ts > ./simple_utility.esm.js +``` + +This section may eventually be automated with GitHub Actions, in which case the bundled scripts will be merged into GitHub Releases, making this step unnecessary. + # Tips This section is not directly related to this module, but provides a few line snippets to help you implement your application. @@ -138,18 +152,5 @@ const {default: data} = await import("./data.json", {assert: {type: "json"}});

-# Browser Compatible -Some methods and classes in this module don't use `globalThis.Deno` internally and are browser compatible. - -I have prepared browser compatible code only export as [mod.compatible.ts](./mod.compatible.ts). - -By bundling this, you can easily create universal utility scripts. - -```sh -deno bundle https://deno.land/x/simple_utility@(version)/mod.compatible.ts > ./simple_utility.esm.js -``` - -This section may eventually be automated with GitHub Actions, in which case the bundled scripts will be merged into GitHub Releases, making this step unnecessary. - # API See [Deno Document](https://deno.land/x/simple_utility/mod.ts) for details. \ No newline at end of file diff --git a/src/core.d.ts b/src/core.d.ts index 7ca18c6..9f1cce1 100644 --- a/src/core.d.ts +++ b/src/core.d.ts @@ -6,4 +6,9 @@ export type SyncFunction = () => T; /** * Function returning arbitrary async types. */ -export type AsyncFunction = SyncFunction>; \ No newline at end of file +export type AsyncFunction = SyncFunction>; + +/** +* The file name and byte array pairs that make up the basic file. +*/ +export type FileInit = [string, Uint8Array]; \ No newline at end of file diff --git a/src/crypto.ts b/src/crypto.ts index 33a058c..a57f536 100644 --- a/src/crypto.ts +++ b/src/crypto.ts @@ -37,6 +37,15 @@ async function deriveSecretKey(kp:PortableCryptoKeyPair){ return await crypto.subtle.deriveKey(dh, privateKey, aes, false, ["encrypt", "decrypt"]); } +/** +* Returns random byte array with the specified number of bytes. +* @param size number of bytes. +* @return random byte array. +*/ +export async function cryptoRandom(size:number){ + return await new Promise(done => done(crypto.getRandomValues(new Uint8Array(size)))); +} + /** * Derive SHA2 hash value from byte array. * @param is512 Use the hash length 512 bits if `true`, 256 bits if `false`. @@ -81,7 +90,7 @@ export async function cryptoEncrypt(kp:PortableCryptoKeyPair, data:Uint8Array){ const gcm:AesGcmParams = { name: "AES-GCM", tagLength: sizeTag * 8, - iv: crypto.getRandomValues(new Uint8Array(sizeIv)) + iv: await cryptoRandom(sizeIv) }; const secretKey = await deriveSecretKey(kp); @@ -107,9 +116,9 @@ export async function cryptoDecrypt(kp:PortableCryptoKeyPair, data:Uint8Array){ iv: data.subarray(0, sizeIv) }; - const commonKey = await deriveSecretKey(kp); + const secretKey = await deriveSecretKey(kp); - return new Uint8Array(await crypto.subtle.decrypt(gcm, commonKey, data.subarray(sizeIv))); + return new Uint8Array(await crypto.subtle.decrypt(gcm, secretKey, data.subarray(sizeIv))); } /** diff --git a/src/minipack.ts b/src/minipack.ts index 7d55763..811f18f 100644 --- a/src/minipack.ts +++ b/src/minipack.ts @@ -1,11 +1,7 @@ +import {type FileInit} from "./core.d.ts"; import {cryptoHash} from "./crypto.ts"; import {ucEncode, ucDecode, hexEncode} from "./text.ts"; -/** -* The file name and byte array pairs that make up the basic file. -*/ -export type FileInit = [string, Uint8Array]; - const sizeHash = 32; const sizeName = 1; const sizeBody = 4; diff --git a/test/crypto.test.ts b/test/crypto.test.ts index 20bba15..2b86e83 100644 --- a/test/crypto.test.ts +++ b/test/crypto.test.ts @@ -1,5 +1,5 @@ import {assertEquals} from "../deps.test.ts"; -import {cryptoHash, cryptoGenerateKey, cryptoEncrypt, cryptoDecrypt, cryptoSign, cryptoVerify} from "../src/crypto.ts"; +import {cryptoRandom, cryptoHash, cryptoGenerateKey, cryptoEncrypt, cryptoDecrypt, cryptoSign, cryptoVerify} from "../src/crypto.ts"; const sample = new Uint8Array([0x02, 0xF2, 0x5D, 0x1F, 0x1C, 0x34, 0xB9, 0x2F]); @@ -14,6 +14,15 @@ const hashResult = new Uint8Array([ 0x0D, 0xE6, 0x31, 0xDA, 0x4B, 0xBD, 0xD4, 0x58 ]); +Deno.test({ + name: "Crypto: Random", + async fn(){ + const random = await cryptoRandom(16); + + assertEquals(random.byteLength, 16); + } +}); + Deno.test({ name: "Crypto: Hash", async fn(){