Merge pull request #1355 from cosmos/revert-node-crypto
Revert "Remove pbkdf2Sha512Crypto and getCryptoModule"
This commit is contained in:
commit
22ef61fa8e
@ -12,10 +12,6 @@ and this project adheres to
|
||||
- all: Add full support for Node.js 18 and run all CI tests with it ([#1240]).
|
||||
- @cosmjs/tendermint-rpc: Remove unused `index` field from `RpcTxEvent` and
|
||||
`TxEvent`. This is unset starting with Tendermint 0.34.
|
||||
- @cosmjs/crypto: The pbkdf2 implementation for old Node.js versions
|
||||
`pbkdf2Sha512Crypto` was removed. Node.js has sufficient support for WebCrypto
|
||||
these days and we still have a pure-JS fallback implementation. This avoids
|
||||
unnecessary problems around importing Node.js modules. ([#1341])
|
||||
- @cosmjs/proto-signing: Make input and output of `decodePubkey` non-optional
|
||||
([#1289]).
|
||||
- @cosmjs/stargate: Remove unnecessary address prefix argument from
|
||||
@ -31,7 +27,6 @@ and this project adheres to
|
||||
[#1289]: https://github.com/cosmos/cosmjs/issues/1289
|
||||
[#1291]: https://github.com/cosmos/cosmjs/issues/1291
|
||||
[#1329]: https://github.com/cosmos/cosmjs/pull/1329
|
||||
[#1341]: https://github.com/cosmos/cosmjs/issues/1341
|
||||
|
||||
## [0.29.5] - 2022-12-07
|
||||
|
||||
|
||||
@ -1,6 +1,13 @@
|
||||
import { fromHex, toAscii, toUtf8 } from "@cosmjs/encoding";
|
||||
|
||||
import { getSubtle, pbkdf2Sha512, pbkdf2Sha512Noble, pbkdf2Sha512Subtle } from "./pbkdf2";
|
||||
import {
|
||||
getNodeCrypto,
|
||||
getSubtle,
|
||||
pbkdf2Sha512,
|
||||
pbkdf2Sha512Noble,
|
||||
pbkdf2Sha512NodeCrypto,
|
||||
pbkdf2Sha512Subtle,
|
||||
} from "./pbkdf2";
|
||||
|
||||
interface TestVector {
|
||||
secret: Uint8Array;
|
||||
@ -139,6 +146,25 @@ describe("pbkdf2", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("pbkdf2Sha512NodeCrypto", () => {
|
||||
it("works", async () => {
|
||||
const nodeCrypto = await getNodeCrypto();
|
||||
if (!nodeCrypto) pending("The crypto module is not available in this environment");
|
||||
|
||||
{
|
||||
const { secret, salt, iterations, keylen, expected } = botanTest;
|
||||
const hash = await pbkdf2Sha512NodeCrypto(nodeCrypto, secret, salt, iterations, keylen);
|
||||
expect(hash).toEqual(expected);
|
||||
}
|
||||
|
||||
for (const [index, test] of brycxTests.entries()) {
|
||||
const { secret, salt, iterations, keylen, expected } = test;
|
||||
const hash = await pbkdf2Sha512NodeCrypto(nodeCrypto, secret, salt, iterations, keylen);
|
||||
expect(hash).withContext(`brycx tests index ${index}`).toEqual(expected);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("pbkdf2Sha512Noble", () => {
|
||||
it("works", async () => {
|
||||
{
|
||||
|
||||
@ -2,6 +2,27 @@ import { assert } from "@cosmjs/utils";
|
||||
import { pbkdf2Async as noblePbkdf2Async } from "@noble/hashes/pbkdf2";
|
||||
import { sha512 as nobleSha512 } from "@noble/hashes/sha512";
|
||||
|
||||
/**
|
||||
* Returns the Node.js crypto module when available and `undefined`
|
||||
* otherwise.
|
||||
*
|
||||
* Detects an unimplemented fallback module from Webpack 5 and returns
|
||||
* `undefined` in that case.
|
||||
*/
|
||||
export async function getNodeCrypto(): Promise<any | undefined> {
|
||||
try {
|
||||
const nodeCrypto = await import("crypto");
|
||||
// We get `Object{default: Object{}}` as a fallback when using
|
||||
// `crypto: false` in Webpack 5, which we interprete as unavailable.
|
||||
if (typeof nodeCrypto === "object" && Object.keys(nodeCrypto).length <= 1) {
|
||||
return undefined;
|
||||
}
|
||||
return nodeCrypto;
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getSubtle(): Promise<any | undefined> {
|
||||
// From Node.js 15 onwards, webcrypto is available in globalThis.
|
||||
// In version 15 and 16 this was stored under the webcrypto key.
|
||||
@ -47,6 +68,33 @@ export async function pbkdf2Sha512Subtle(
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements pbkdf2-sha512 using the Node.js crypro module (`import "crypto"`).
|
||||
* This does not use subtle from [Crypto](https://developer.mozilla.org/en-US/docs/Web/API/Crypto).
|
||||
*/
|
||||
export async function pbkdf2Sha512NodeCrypto(
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
nodeCrypto: any,
|
||||
secret: Uint8Array,
|
||||
salt: Uint8Array,
|
||||
iterations: number,
|
||||
keylen: number,
|
||||
): Promise<Uint8Array> {
|
||||
assert(nodeCrypto, "Argument nodeCrypto is falsy");
|
||||
assert(typeof nodeCrypto === "object", "Argument nodeCrypto is not of type object");
|
||||
assert(typeof nodeCrypto.pbkdf2 === "function", "nodeCrypto.pbkdf2 is not a function");
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
nodeCrypto.pbkdf2(secret, salt, iterations, keylen, "sha512", (error: any, result: any) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
resolve(Uint8Array.from(result));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export async function pbkdf2Sha512Noble(
|
||||
secret: Uint8Array,
|
||||
salt: Uint8Array,
|
||||
@ -69,6 +117,11 @@ export async function pbkdf2Sha512(
|
||||
if (subtle) {
|
||||
return pbkdf2Sha512Subtle(subtle, secret, salt, iterations, keylen);
|
||||
} else {
|
||||
return pbkdf2Sha512Noble(secret, salt, iterations, keylen);
|
||||
const nodeCrypto = await getNodeCrypto();
|
||||
if (nodeCrypto) {
|
||||
return pbkdf2Sha512NodeCrypto(nodeCrypto, secret, salt, iterations, keylen);
|
||||
} else {
|
||||
return pbkdf2Sha512Noble(secret, salt, iterations, keylen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user