-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: use native crypto functions (#61)
* chore: use webcrypto for pbkdf2 * Use webcrypto for aes and sha256 * Remove unnecessary type cast * Remove export * chore: simplify * chore: use node crypto * chore: refactor environment sensing * chore: add comments * chore: refactor * chore: cleanup kdf interfaces --------- Co-authored-by: Nico Flaig <[email protected]>
- Loading branch information
1 parent
20f0b33
commit 750d2e8
Showing
9 changed files
with
172 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { sha256 as _sha256 } from "ethereum-cryptography/sha256"; | ||
|
||
import { hasWebCrypto } from "../env"; | ||
|
||
export const sha256 = hasWebCrypto ? sha256WebCrypto : sha256Js; | ||
|
||
async function sha256WebCrypto(data: Uint8Array): Promise<Uint8Array> { | ||
return new Uint8Array(await crypto.subtle.digest("SHA-256", data)); | ||
} | ||
|
||
async function sha256Js(data: Uint8Array): Promise<Uint8Array> { | ||
return _sha256(data); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import { encrypt as aesEncrypt, decrypt as aesDecrypt } from "ethereum-cryptography/aes"; | ||
|
||
import { hasWebCrypto } from "../env"; | ||
|
||
export const aes128CtrEncrypt = hasWebCrypto ? aes128CtrEncryptWebCrypto : aes128CtrEncryptJs; | ||
export const aes128CtrDecrypt = hasWebCrypto ? aes128CtrDecryptWebCrypto : aes128CtrDecryptJs; | ||
|
||
export async function aes128CtrEncryptJs(key: Uint8Array, iv: Uint8Array, data: Uint8Array): Promise<Uint8Array> { | ||
return await aesEncrypt( | ||
data, | ||
key, | ||
iv, | ||
"aes-128-ctr", | ||
false, | ||
); | ||
} | ||
|
||
async function aes128CtrEncryptWebCrypto( | ||
key: Uint8Array, | ||
iv: Uint8Array, | ||
data: Uint8Array | ||
): Promise<Uint8Array> { | ||
const cryptoKey = await crypto.subtle.importKey( | ||
"raw", | ||
key, | ||
{name: "AES-CTR"}, | ||
false, | ||
["encrypt"] | ||
); | ||
return new Uint8Array(await crypto.subtle.encrypt( | ||
{ name: "AES-CTR", counter: iv, length: 128 }, | ||
cryptoKey, | ||
data | ||
)); | ||
} | ||
|
||
export async function aes128CtrDecryptJs(key: Uint8Array, iv: Uint8Array, ciphertext: Uint8Array): Promise<Uint8Array> { | ||
return await aesDecrypt( | ||
ciphertext, | ||
key, | ||
iv, | ||
"aes-128-ctr", | ||
false, | ||
); | ||
} | ||
|
||
async function aes128CtrDecryptWebCrypto(key: Uint8Array, iv: Uint8Array, ciphertext: Uint8Array): Promise<Uint8Array> { | ||
const cryptoKey = await crypto.subtle.importKey( | ||
"raw", | ||
key, | ||
{name: "AES-CTR"}, | ||
false, | ||
["decrypt"] | ||
); | ||
return new Uint8Array(await crypto.subtle.decrypt( | ||
{ name: "AES-CTR", counter: iv, length: 128 }, | ||
cryptoKey, | ||
ciphertext | ||
)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
/** Is in nodejs environment */ | ||
export const isNode = | ||
typeof process !== "undefined" && | ||
process.versions != null && | ||
process.versions.node != null; | ||
|
||
/** Is in environment with web crypto */ | ||
export const hasWebCrypto = globalThis?.crypto?.subtle != null; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { pbkdf2 } from "ethereum-cryptography/pbkdf2"; | ||
|
||
import { hasWebCrypto, isNode } from "../env"; | ||
|
||
export const doPbkdf2 = isNode ? doPbkdf2Node : hasWebCrypto ? doPbkdf2WebCrypto : doPbkdf2Js; | ||
|
||
async function doPbkdf2Js(salt: Uint8Array, c: number, dklen: number, password: Uint8Array): Promise<Uint8Array> { | ||
return pbkdf2( | ||
password, | ||
salt, | ||
c, | ||
dklen, | ||
"sha256", | ||
); | ||
} | ||
|
||
async function doPbkdf2Node(salt: Uint8Array, c: number, dklen: number, password: Uint8Array): Promise<Uint8Array> { | ||
const crypto = await import("crypto"); | ||
return crypto.pbkdf2Sync(password, salt, c, dklen, "sha256"); | ||
} | ||
|
||
async function doPbkdf2WebCrypto(salt: Uint8Array, c: number, dklen: number, password: Uint8Array): Promise<Uint8Array> { | ||
const passwordKey = await crypto.subtle.importKey( | ||
"raw", | ||
password, | ||
{name: "PBKDF2"}, | ||
false, | ||
["deriveBits"], | ||
); | ||
return new Uint8Array(await crypto.subtle.deriveBits( | ||
{ | ||
name: "PBKDF2", | ||
salt, | ||
iterations: c, | ||
hash: "SHA-256", | ||
}, | ||
passwordKey, | ||
dklen * 8, | ||
)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { scrypt } from "ethereum-cryptography/scrypt"; | ||
|
||
import { isNode } from "../env"; | ||
|
||
|
||
export const doScrypt = isNode ? doScryptNode : doScryptJs; | ||
|
||
async function doScryptJs(salt: Uint8Array, n: number, p: number, r: number, dklen: number, password: Uint8Array): Promise<Uint8Array> { | ||
return scrypt( | ||
password, | ||
salt, | ||
n, | ||
p, | ||
r, | ||
dklen, | ||
); | ||
} | ||
|
||
async function doScryptNode(salt: Uint8Array, n: number, p: number, r: number, dklen: number, password: Uint8Array): Promise<Uint8Array> { | ||
const crypto = await import("crypto"); | ||
return crypto.scryptSync( | ||
password, | ||
salt, | ||
dklen, { | ||
N: n, | ||
r, | ||
p, | ||
maxmem: n * r * 256, | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters