peculiarventures / webcrypto Goto Github PK
View Code? Open in Web Editor NEWA WebCrypto Polyfill for NodeJS
License: MIT License
A WebCrypto Polyfill for NodeJS
License: MIT License
I've been using the https://github.com/PeculiarVentures/x509 library.
At first since webcrypto already available in nodejs, I thought it was sufficient to do this:
x509.cryptoProvider.set(webcrypto as Crypto);
However subsequently I found that that there's an API difference between the way x509 expects Ed25519 algorithm objects that are based on this library, compared to the ones that in NodeJS (https://nodejs.org/api/webcrypto.html#ed25519ed448x25519x448-key-pairs).
For example in NodeJS's webcrypto, the alg
parameter can just be: { name: 'Ed25519' }
.
However for peculiar's webcrypto, the alg
parameter has to be { name: 'EdDSA', namedCurve: 'Ed25519' }
.
This caused some incompatibilities in webcrypto.subtle.importKey
and in x509.X509CertificateGenerator.createSelfSigned
In the case of the importKey
, I have to use a webcrypto's expected alg parameter:
const privateCryptoKey = await webcrypto.subtle.importKey(
'jwk',
privateKeyJWK,
// { name: 'Ed25519' }, // This is nodejs webcrypto
{ name: 'EdDSA', namedCurve: 'Ed25519' }, // This is peculiar's webcrypto
true,
['sign']
);
During the generation of the certificate, if I used node's webcrypto, the certificate generation works without exceptions, however I notice that the signatureAlgorithm
field is empty, and stays as:
signatureAlgorithm: { name: '', parameters: undefined },
The resulting certificate when output to PEM is not readable by openssl x509 -in ./tmp/cert -text
.
unable to load certificate
140330083047232:error:0D0C40D8:asn1 encoding routines:c2i_ASN1_OBJECT:invalid object encoding:crypto/asn1/a_object.c:254:
140330083047232:error:0D08303A:asn1 encoding routines:asn1_template_noexp_d2i:nested asn1 error:crypto/asn1/tasn_dec.c:646:Field=algorithm, Type=X509_ALGOR
140330083047232:error:0D08303A:asn1 encoding routines:asn1_template_noexp_d2i:nested asn1 error:crypto/asn1/tasn_dec.c:646:Field=signature, Type=X509_CINF
140330083047232:error:0D08303A:asn1 encoding routines:asn1_template_noexp_ d2i:nested asn1 error:crypto/asn1/tasn_dec.c:646:Field=cert_info, Type=X509 AES-GCM', length: 256 },
140330083047232:error:0906700D:PEM routines:PEM_ASN1_read_bio:ASN1 lib:crypto/pem/pem_oth.c:33:
CUSTOM CALLED
So it seems that if I want to use ed25519 with https://github.com/PeculiarVentures/x509, I have to use peculiar's webcrypto and not node's webcrypto.
The HmacCryptoKey and AesCryptoKey interfaces wrongfully require the alg
attribute to be present when importing keyData in jwk
key format.
Every other webcrypto runtime allows these to omitted and in order to have interoperable behaviour between runtimes it is in fact better to remove the alg
attribute.
I am generating keys with ecdh
const { Crypto } = require("@peculiar/webcrypto");
const crypto = new Crypto();
const { publicKey, privateKey } = await crypto.subtle.generateKey(
{
name: "ECDH",
namedCurve: "P-256", // P-256, P-384, or P-521
},
true,
["deriveKey", "deriveBits"],
);
but when exporting them it throws me this error
Error: Cannot get schema for 'PrivateKeyInfo' target
Can someone guide me how to solve this problem?
i noticed the es module has an "all rights reserved" banner, which is in seeming conflict with the MIT license presented at the project root
Line 6 in 47976a9
Currently, we want to use 3072-bit for RSA key's modulusLength but as I checked the current source code:
webcrypto/src/mechs/rsa/rsa_es.ts
Line 51 in a1760f2
We only support 1024, 2048, and 4096 modulusLength. Could I ask that why we don't support 3072-bit value here?
I've tested @peculiar/webcrypto package 1.4.3 on node 21.1.0 and verified that's it's vulnerable to the Marvin Attack.
The size of the side channel is very large, so even remote exploitation will be rather easy. Both correctness of the PKCS#1 v1.5 ciphertext is leaking as well as the length of the returned message. Less than 100 measurements per probe are necessary for highly statistically significant results, so a local attack taking as little as few hours is quite realistic.
I've executed the reproducer in the marvin-toolkit repo on an AMD Ryze 5 5600X CPU running with core isolation.
After collecting 10 thousand measurements per sample, I've got the following results:
Sign test mean p-value: 0.3282, median p-value: 0.2048, min p-value: 0.0
Friedman test (chisquare approximation) for all samples
p-value: 0.0
Worst pair: 6(valid_48), 11(zero_byte_in_padding_48_4)
Mean of differences: 1.39286e-05s, 95% CI: -3.92232e-06s, 3.116315e-05s (±1.754e-05s)
Median of differences: 2.03415e-05s, 95% CI: 2.01400e-05s, 2.054000e-05s (±2.000e-07s)
Trimmed mean (5%) of differences: 2.02399e-05s, 95% CI: 2.00630e-05s, 2.041578e-05s (±1.764e-07s)
Trimmed mean (25%) of differences: 2.02831e-05s, 95% CI: 2.01000e-05s, 2.045879e-05s (±1.794e-07s)
Trimmed mean (45%) of differences: 2.03165e-05s, 95% CI: 2.01283e-05s, 2.050997e-05s (±1.908e-07s)
Trimean of differences: 2.02808e-05s, 95% CI: 2.01023e-05s, 2.045544e-05s (±1.766e-07s)
Layperson explanation: Definite side-channel detected, implementation is VULNERABLE
With a graph of confidence intervals of:
legend for the graph:
ID,Name
0,header_only
1,no_header_with_payload_48
2,no_padding_48
3,no_structure
4,signature_padding_8
5,valid_0
6,valid_48
7,valid_192
8,valid_246
9,valid_repeated_byte_payload_246_1
10,valid_repeated_byte_payload_246_255
11,zero_byte_in_padding_48_4
explanation of the probes is in the step2.py script.
Results of the pairwise statistical tests are in this file:
report.txt
note: the p-values of 0 mean that the actual calculated p-value is smaller than what double precision floating point number can represent
Hi,
thanks for this great wrapper.
I think from node version 15.14.0 there is webcrypto in the official crytpo library.
like so: require('crypto').webcrypto
this might be a good idea to offer isomorphic package.
thanks!
We are currently blocked on implementing RSA OAEP based encryption by this bug:
nodejs/help#1726. Without this, we will not be able to deprecate the node-webcrypto-ossl
library.
jwk.alg
(if presents) with algorithm
argument and throw DOMException
if they are not equalvar key = await crypto.subtle.generateKey({name: "AES-CBC", length: 256}, true, ["encrypt", "decrypt"]);
var jwk = await crypto.subtle.exportKey("jwk", key);
delete jwk.key_ops
var hmacKey = await crypto.subtle.importKey("jwk", jwk, {name: "AES-KW"}, false, ["wrapKey"]);
DOMException: The JWK "alg" member was inconsistent with that specified by the Web Crypto call
jwk.key_ops
(if presents) with keyUsages
argument and throw DOMException
if they are not equalvar key = await crypto.subtle.generateKey({name: "AES-CBC", length: 256}, true, ["encrypt", "decrypt"]);
var jwk = await crypto.subtle.exportKey("jwk", key);
var hmacKey = await crypto.subtle.importKey("jwk", jwk, {name: "AES-KW"}, false, ["wrapKey"]);
DOMException: The JWK "key_ops" member was inconsistent with that specified by the Web Crypto call. The JWK usage must be a superset of those requested
Was running it on Node.js v8.6 and got error
TypeError: crypto.generateKeyPairSync is not a function
So, it is necessary to state somewhere in docs that the package would work only with Node v10.12.0 and higher. Or redesign the package by removing generateKeyPairSync
usage.
The algorithm HKDF is missing from this library. (According to https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto)
I would love to create a PR to add it, however it seems like webcrypto-core
does not support an HKDF provider.
ArrayBufferViews are not required to be aligned with their underlying .buffer
property. Instead of:
Line 10 in 012a63f
do:
const buffer = Buffer.from(array.buffer, array.byteOffset, array.byteLength)
I upgraded from 1.1.3 to 1.1.4, and a series of tests have started to fail. All of them fail when using exportKey
. For example:
Error: Cannot get CryptoKey from secure storage
at getCryptoKey (node_modules/@relaycorp/relaynet-core/node_modules/@peculiar/webcrypto/build/webcrypto.js:91:15)
at RsaPssProvider.checkCryptoKey (node_modules/@relaycorp/relaynet-core/node_modules/@peculiar/webcrypto/build/webcrypto.js:1044:29)
at RsaPssProvider.checkExportKey (node_modules/webcrypto-core/build/webcrypto-core.js:207:14)
at RsaPssProvider.exportKey (node_modules/webcrypto-core/build/webcrypto-core.js:202:29)
at SubtleCrypto.exportKey (node_modules/webcrypto-core/build/webcrypto-core.js:838:39)
at CryptoEngine.exportKey (node_modules/pkijs/src/CryptoEngine.js:604:30)
at Object.derSerializePublicKey (node_modules/@relaycorp/relaynet-core/src/lib/crypto_wrappers/keys.ts:76:43)
at PoWebClient.preRegisterNode (src/lib/PoWebClient.ts:123:43)
at Object.<anonymous> (src/lib/PoWebClient.spec.ts:223:20)
Having seeing the changes between the two releases (https://github.com/PeculiarVentures/webcrypto/compare/v1.1.3..v1.1.4), I thought the culprit could've been the upgrade of webcrypto-core, but I couldn't see any change in it that could lead to this behaviour (https://github.com/PeculiarVentures/webcrypto-core/compare/v1.1.6..v1.1.8).
When @peculiar/webcrypto
is used as a crypto engine, RSA public key re-export result is invalid.
Here is a sample code:
import { Crypto } from '@peculiar/webcrypto';
const crypto = new Crypto();
const algorithm = {
name: 'RSASSA-PKCS1-v1_5',
hash: 'SHA-256',
publicExponent: new Uint8Array([1, 0, 1]),
modulusLength: 2048,
};
const keys = await crypto.subtle.generateKey(algorithm, true, ['sign', 'verify'])
const cryptoKeyBuffer = await crypto.subtle.exportKey('spki', keys.publicKey);
console.log(cryptoKeyBuffer.byteLength); // will log 294
const reImportedKey = await crypto.subtle.importKey('spki', cryptoKeyBuffer, algorithm, true, ['verify']);
const reExportedKey = await crypto.subtle.exportKey('spki', reImportedKey);
console.log(reExportedKey.byteLength); // will log 22, invalid bytelength.
The same code for WebCrypto in browser implementation or WebCrypto in the node will result in a valid re-exported buffer with the same length and ability to import/export countless times.
Hey all!
I am trying to get the package to work with react-native and gundb but facing a couple of errors and warnings. Below is one of the more confusing warnings I am getting. Hopefully someone recognizes it and offers some insight.
[webview-crypto] error in
parseof message: "%7B%22id%22%3A%22c510-9fc9-53c0-72ed-63de-5b05-7515-35a7%22%2C%22value%22%3A%7B%22__serializer_id%22%3A%22CryptoKey%22%2C%22value%22%3A%7B%22serialized%22%3Atrue%2C%22_import%22%3A%7B%22format%22%3A%22raw%22%2C%22keyData%22%3A%7B%22__serializer_id%22%3A%22ArrayBufferView%22%2C%22value%22%3A%7B%22name%22%3A%22Uint8Array%22%2C%22buffer%22%3A%7B%22__serializer_id%22%3A%22ArrayBuffer%22%2C%22value%22%3A%22password%22%7D%7D%7D%7D%2C%22type%22%3A%22secret%22%2C%22extractable%22%3Afalse%2C%22algorithm%22%3A%7B%22name%22%3A%22PBKDF2%22%7D%2C%22usages%22%3A%5B%22deriveBits%22%5D%7D%7D%7D" reason: {"name":"ReferenceError","message":"Property 'abvs' doesn't exist","stack":"ReferenceError: Property 'abvs' doesn't exist\n at eval (JavaScript:1:16)\n at anonymous
Thanks!
var keyDatasource = new Uint8Array([0,221,184,11,6,126,13,73,147,25,127,225,15,38,87,168,68,163,132,88,152,71,96,45,86,240,198,41,200,26,174,50,1,210,138,62,83,207,250,65,158,193,34,201,104,179,37,158,22,182,80,118,73,84,148,217,124,174,16,187,254,195,195,111])
var rawKey = keyDatasource.subarray(32, 64)
var key = await crypto.subtle.importKey('raw', rawKey, {name:'HMAC', hash:'SHA-512'}, true, ['sign'])
var exportedKey = new Uint8Array(await crypto.subtle.exportKey('raw', key))
assert(exportedKey.length === 64) // should be 32
Tested in browser, the byte offset is respected and the imported key is the latter 32 bytes of the source data. In this library, the imported key is all 64 bytes of the underlying ArrayBuffer
.
I use Jest and TS with ESM mode:
"jest": {
"preset": "ts-jest/presets/default-esm",
"globals": {
"ts-jest": {
"useESM": true
}
},
"testEnvironment": "jsdom"
}
node --experimental-vm-modules node_modules/.bin/jest
After switching to ESM I start to have ArrayBuffer
error:
TypeError: The provided value is not of type '(ArrayBuffer or ArrayBufferView)'
52 | let key
53 | async function getKey () {
> 54 | key = await crypto.subtle.importKey(
| ^
55 | 'raw',
56 | await sha256(secret),
57 | { name: 'AES-GCM' },
at Function.toUint8Array (node_modules/pvtsutils/build/index.js:29:17)
at Function.toArrayBuffer (node_modules/pvtsutils/build/index.js:13:28)
at SubtleCrypto.importKey (node_modules/webcrypto-core/build/webcrypto-core.js:847:66)
at getKey (encrypt-actions/index.js:54:31)
at outMap (encrypt-actions/index.js:69:23)
at syncMappedEvent (node_modules/@logux/core/base-node/index.js:37:21)
Sources:
function sha256 (string) {
return crypto.subtle.digest('SHA-256', new TextEncoder().encode(string))
}
let key
async function getKey () {
key = await crypto.subtle.importKey(
'raw',
await sha256(secret),
{ name: 'AES-GCM' },
false,
['encrypt', 'decrypt']
)
return key
}
Seems like switching to ESM created two ArrayBuffer
instances and data instanceof ArrayBuffer
start to return false
.
Will it be more stable to now using instanceof
?
Object.prototype.toString.call(value) === '[object ArrayBuffer]'
TypeScript 4.6.2 was just released and added crypto.randomUUID()
in microsoft/TypeScript@4e689bc
This causes @peculiar/webcrypto
to fail to build.
Create a new project and install the latest dependencies.
mkdir example
cd example
npm init -y
npm install @peculiar/[email protected] [email protected]
echo '{ "compilerOptions": { "module": "commonjs" } }' > tsconfig.json
echo 'import { Crypto } from "@peculiar/webcrypto"' > index.ts
./node_modules/.bin/tsc
@peculiar/webcrypto/index.d.ts:1:22 - error TS2420: Class 'import("@peculiar/webcrypto/index").Crypto' incorrectly implements interface 'Crypto'.
Property 'randomUUID' is missing in type 'import("@peculiar/webcrypto/index").Crypto' but required in type 'Crypto'.
1 export declare class Crypto implements globalThis.Crypto {
~~~~~~
node_modules/typescript/lib/lib.dom.d.ts:3652:5
3652 randomUUID(): string;
You'd get an error like this:
Error: Unknown cipher
at Cipheriv.createCipherBase (node:internal/crypto/cipher:116:19)
at Cipheriv.createCipherWithIV (node:internal/crypto/cipher:135:3)
at new Cipheriv (node:internal/crypto/cipher:243:3)
at Object.createCipheriv (node:crypto:138:10)
at Function.encryptAesKW (/home/gus/repos/awala-gateway-desktop/packages/ui/app/node_modules/daemon/node_modules/@peculiar/webcrypto/build/webcrypto.js:260:51)
at Function.encrypt (/home/gus/repos/awala-gateway-desktop/packages/ui/app/node_modules/daemon/node_modules/@peculiar/webcrypto/build/webcrypto.js:182:29)
at AesKwProvider.onEncrypt (/home/gus/repos/awala-gateway-desktop/packages/ui/app/node_modules/daemon/node_modules/@peculiar/webcrypto/build/webcrypto.js:506:26)
at AesKwProvider.encrypt (/home/gus/repos/awala-gateway-desktop/packages/ui/app/node_modules/daemon/node_modules/webcrypto-core/build/webcrypto-core.js:184:31)
at SubtleCrypto.wrapKey (/home/gus/repos/awala-gateway-desktop/packages/ui/app/node_modules/daemon/node_modules/webcrypto-core/build/webcrypto-core.js:1393:25)
at async Promise.all (index 0)
This is due to electron/electron#31874
This means that you can't use PKI.js with EnvelopedData
and DH, for example.
I don't think there's anything to change in this repo, but I wanted to create this issue to save some time to anyone that comes across this issue. Feel free to close it.
Hi,
Great work !
I'm currently switching from CryptoJS and couldn't figure out how to reach this outcome:
var encrypted = CryptoJS.AES.encrypt("Message", "Secret Passphrase");
var decrypted = CryptoJS.AES.decrypt(encrypted, "Secret Passphrase");
Any hint please?
Thank you again for the quality of this repo
Hello,
I am using pki.js library with node-webcrypto-ossl in an electron app. While using node-webcrypto-ossl on windows for electron it produces various error and I was thinking of migrating to this library. Is there any difference between this library and node-webcrypto-ossl? Will it be fine to use any as replacement in any project?
Hello!
I'm trying to use the library in a react app, but getting an error trying to generate basic keys:
crypto__WEBPACK_IMPORTED_MODULE_1___default.a.generateKeyPairSync is not a function
const crypto = new Crypto(); await crypto.subtle.generateKey( { name: 'ECDH', namedCurve: 'P-256', true, ['deriveBits'] );
Should the webcrypto library actually work in the browser, or have I missed something in the docs?
Hey, I'm trying to use your implementation of subtle crypto in a package (https://github.com/QuestNetwork/quest-pubsub-js) to make it portable for use in nodejs and in an angular browser/electron app. Works great for my nodejs test case, but unfortunately the browser/electron app (angular 9) throws the error in title. Any clue what's going on there? If it's a browser related issue, maybe you could test if subtle crypto is available and use that when it's possible instead of your package or should I be doing that in my package (It's what I'm doing right now)? What's your perspective?
PS: Also considered just browserifying but feels kind of ridiculous
Hi,
I am trying to migrate my code from node-webcrypto-ossl to webcrypto.
I have a problem that exportkey of an hmac key returns octet instead of oct as kty.
This is my flow:
key generation
let key = await this._crypto.subtle.generateKey(
{ hash:"SHA-256", name:"hmac"},
true,
["sign"]
);
exportkey
const jwk = await this._crypto.subtle.exportKey(
'jwk',
key);
results in:
{
alg:"HS256"
ext:true
k:"ji4zeVsT2I7ZkzKomSTSSXxaj7cq33U5mbs2SMrdAsA"
key_ops: ["sign"]
kty:"octet"
}
Can you change kty to oct as it should be?
Thanks
In a number of files I find that there are cjs require
statements even though they otherwise use import
. Is there some specific reason for this? It is making my bundler mad. Please fix!
currently importKey
and exportKey
methods work only on public keys, but not on privateKeys.
node14.5安装失败
错误提示
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE package: '[email protected]',
npm WARN EBADENGINE required: { node: '^12.22.0 || ^14.17.0 || >=16.0.0' },
npm WARN EBADENGINE current: { node: 'v14.15.0', npm: '7.24.1' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE package: '[email protected]',
npm WARN EBADENGINE required: { node: '^12.22.0 || ^14.17.0 || >=16.0.0' },
npm WARN EBADENGINE current: { node: 'v14.15.0', npm: '7.24.1' }
npm WARN EBADENGINE }
I am hitting the following error in an nw.js (which is an electron like) environment:
Error: Wrong parameter: inputBuffer must be "ArrayBuffer"
at Function.parse
at RsaPublicKey.getKey
at RsaPublicKey.toJSON
at Function.toJSON
at Function.exportKey
at RsaSsaProvider.onExportKey
at RsaSsaProvider.exportKey
at SubtleCrypto.exportKey
at crypto.subtle.generateKey.then
(Sorry about the line numbers, I am pulling these out of a bundle and sourcemaps are giving me grief)
The happens at crypto.subtle.exportKey
in the snippet below. This is despite the fact that the key is being generated by this library itself. The key is generated and exported using the following code:
static generateSessionKeys () {
return crypto.subtle.generateKey(
{
name: "RSASSA-PKCS1-v1_5",
modulusLength: 2048,
publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
hash: { name: "SHA-256" },
},
true,
["sign", "verify"]
)
.then((keyPair) => {
// returns a keypair object
return Promise.all([
crypto.subtle.exportKey('jwk', keyPair.publicKey),
crypto.subtle.exportKey('jwk', keyPair.privateKey)
])
})
}
Currently, it seems that Electron does not correctly implement WebCrypto interfaces. Specifically it seems that It doesn't have generateKey functions. Without this, we will not be able to deprecate the node-webcrypto-ossl
library.
As shown in the snipped below, this library isn't currently honouring the hashing algorithm or setting a salt length when generating RSA-PSS keys, as it wasn't supported in older versions of Node.js:
webcrypto/src/mechs/rsa/crypto.ts
Lines 37 to 48 in 37dff39
I think this crypto.generateKeyPairSync()
call should be changed to set the type to rsa-pss
(only if using RSA-PSS) and add the following options if the current Node.js version is >= 16.10.0:
hashAlgorithm
and mgf1HashAlgorithm
: This value is already available in the context (algorithm.hash.name
).saltLength
: Should match the length of the digest from hashAlgorithm
(e.g., 32
for SHA-256), following industry best practices (see, for example, TLS 1.3 and GCP KMS key algorithms).I suspect this might be a breaking change in those apps/libs using the default values of MGF1 with SHA-1 and saltLength=20
(I think PKI.js' SignedData
and Certificate
might be affected from a cursory look at CryptoEngine
but haven't had the time to double check).
`import { Crypto } from "@peculiar/webcrypto";
// GENERATE AND EXPORT KEYS
export async function generateKeysTest() {
const WebCrypto = new Crypto();
const { publicKey, privateKey } = await WebCrypto.subtle.generateKey(
{
name: "RSA-PSS",
modulusLength: 2048,
publicExponent: new Uint8Array([1, 0, 1]),
hash: "SHA-256"
},
true,
["sign", "verify"]
);
const publicExport = await WebCrypto.subtle.exportKey("spki", publicKey);
const privateExport = await WebCrypto.subtle.exportKey("pkcs8", privateKey);
const pubExportedAsString = ab2str(publicExport);
const pubExportedAsBase64 = stringToBase64(pubExportedAsString);
const publicKeyPem = ${pubExportedAsBase64}
;
const privExportedAsString = ab2str(privateExport);
const privExportedAsBase64 = stringToBase64(privExportedAsString);
const privateKeyPem = ${privExportedAsBase64}
;
// IMPORT KEYS
const pubKeyImportedAsString = base64ToString(publicKeyPem);
const pubKeyImportedAsArrayBuffer = str2ab(pubKeyImportedAsString);
const publicKeyImport = await WebCrypto.subtle.importKey(
"spki",
pubKeyImportedAsArrayBuffer,
{ name: "RSA-PSS", hash: "SHA-256" },
true,
["verify"]
);
const privateKeyImportedAsString = base64ToString(privateKeyPem);
const privateKeyImportedAsArrayBuffer = str2ab(privateKeyImportedAsString);
const privateKeyImport = await WebCrypto.subtle.importKey(
"pkcs8",
privateKeyImportedAsArrayBuffer,
{ name: "RSA-PSS", hash: "SHA-256" },
true,
["sign"]
);
}
// HELPERS
const ab2str = (buffer: ArrayBuffer) => String.fromCharCode.apply(null, Array.from(new Uint8Array(buffer)));
const str2ab = (str: string): ArrayBuffer => {
const buffer = new ArrayBuffer(str.length * 2);
const bufferInterface = new Uint8Array(buffer);
Array.from(str).forEach((_, index: number) => (bufferInterface[index] = str.charCodeAt(index)));
return buffer;
};
function stringToBase64(value: string) {
return Buffer.from(value).toString("base64");
}
function base64ToString(encryptedString: string) {
return Buffer.from(encryptedString, "base64").toString("binary");
}
`
I'm trying to generate the key, export it and import back, but on key import i get "Too big integer error".
Hi there,
Thank you very much for providing this repository
can you please merge the pull request of dependabot to fix the vulnerability: GHSA-9c47-m6qq-7p4h
Thank you!
I'm trying to bundle the PageSigner pgsg-node.js (written in NodeJS) using browserify, such that I can run it via QuickJS and eventually compile it to WASM. (Not for a browser application however - I need to run it on a WASM VM).
After some necessary edits to the code of pgsg-node.js, I managed to successfully execute both node bundle.js
and the QuickJS analogue qjs bundle.js
and log the final output to the console. However, that only works if I remove this crucial line:
var result = await crypto.subtle.verify({'name':'ECDSA', 'hash':'SHA-256'}, notary_pk_CryptoKey, ba2ab(sig_p1363), ba2ab(signed_data_ba))
and replace it with var result = true
. Otherwise I get the following error after executing node bundle.js
:
Error: Unknown message digest
at new Verify (/home/metzgerj/CoaseContract/pagesigner/webextension/content/pgsg-node/bundle.js:13849:20)
at Object.createVerify (/home/metzgerj/CoaseContract/pagesigner/webextension/content/pgsg-node/bundle.js:13882:10)
at Function.verify (/home/metzgerj/CoaseContract/pagesigner/webextension/content/pgsg-node/bundle.js:33318:51)
at EcdsaProvider.onVerify (/home/metzgerj/CoaseContract/pagesigner/webextension/content/pgsg-node/bundle.js:33496:25)
at EcdsaProvider.verify (/home/metzgerj/CoaseContract/pagesigner/webextension/content/pgsg-node/bundle.js:82175:30)
at SubtleCrypto.verify (/home/metzgerj/CoaseContract/pagesigner/webextension/content/pgsg-node/bundle.js:82832:39)
at verifyNotarySig (/home/metzgerj/CoaseContract/pagesigner/webextension/content/pgsg-node/bundle.js:2724:39)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at async verifyPgsgV4 (/home/metzgerj/CoaseContract/pagesigner/webextension/content/pgsg-node/bundle.js:723:10)
at async Object.verifyPgsg (/home/metzgerj/CoaseContract/pagesigner/webextension/content/pgsg-node/bundle.js:661:12) Error
(node:7830) UnhandledPromiseRejectionWarning: Error: Unknown message digest
at new Verify (/home/metzgerj/CoaseContract/pagesigner/webextension/content/pgsg-node/bundle.js:13849:20)
at Object.createVerify (/home/metzgerj/CoaseContract/pagesigner/webextension/content/pgsg-node/bundle.js:13882:10)
at Function.verify (/home/metzgerj/CoaseContract/pagesigner/webextension/content/pgsg-node/bundle.js:33318:51)
at EcdsaProvider.onVerify (/home/metzgerj/CoaseContract/pagesigner/webextension/content/pgsg-node/bundle.js:33496:25)
at EcdsaProvider.verify (/home/metzgerj/CoaseContract/pagesigner/webextension/content/pgsg-node/bundle.js:82175:30)
at SubtleCrypto.verify (/home/metzgerj/CoaseContract/pagesigner/webextension/content/pgsg-node/bundle.js:82832:39)
at verifyNotarySig (/home/metzgerj/CoaseContract/pagesigner/webextension/content/pgsg-node/bundle.js:2724:39)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at async verifyPgsgV4 (/home/metzgerj/CoaseContract/pagesigner/webextension/content/pgsg-node/bundle.js:723:10)
at async Object.verifyPgsg (/home/metzgerj/CoaseContract/pagesigner/webextension/content/pgsg-node/bundle.js:661:12)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:7830) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:7830) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
What's weird is that at least some of the crypto.subtle
functionality works, the line right before
var notary_pk_CryptoKey = await crypto.subtle.importKey(
"raw", ba2ab(notaryPubkey_ba), {name: 'ECDSA', namedCurve:'P-256'}, true, ["verify"]);
works flawlessly. Also, executing my modified unbundled file node pgsg-node.js
does not produce this error.
Hello,
Is this library supposed to work in a browser? I'm hitting the below error in a fresh Vite app using v1.1.6
.
Pre-bundling dependencies:
@peculiar/webcrypto
(this will be run only when your dependencies or config have changed)
> node_modules/@peculiar/webcrypto/build/webcrypto.es.js:7:17: error: No matching export in "browser-external:crypto" for import "createCipheriv"
7 │ import crypto, { createCipheriv, publicEncrypt, privateDecrypt, constants } from 'crypto';
╵ ~~~~~~~~~~~~~~
> node_modules/@peculiar/webcrypto/build/webcrypto.es.js:7:33: error: No matching export in "browser-external:crypto" for import "publicEncrypt"
7 │ import crypto, { createCipheriv, publicEncrypt, privateDecrypt, constants } from 'crypto';
╵ ~~~~~~~~~~~~~
> node_modules/@peculiar/webcrypto/build/webcrypto.es.js:7:48: error: No matching export in "browser-external:crypto" for import "privateDecrypt"
7 │ import crypto, { createCipheriv, publicEncrypt, privateDecrypt, constants } from 'crypto';
╵ ~~~~~~~~~~~~~~
> node_modules/@peculiar/webcrypto/build/webcrypto.es.js:7:64: error: No matching export in "browser-external:crypto" for import "constants"
7 │ import crypto, { createCipheriv, publicEncrypt, privateDecrypt, constants } from 'crypto';
╵ ~~~~~~~~~
> node_modules/@peculiar/webcrypto/build/webcrypto.es.js:8:9: error: No matching export in "browser-external:process" for import "version"
8 │ import { version } from 'process';
╵ ~~~~~~~
IIUC, the above error is because crypto
and process
are included as external
node objects in rollup.config.js
. Is there a missing shim for use in the browser?
With the latest release of this library v1.1.7 I get the following error
Cannot get schema for 'PrivateKeyInfo' target
When running the following
const crypto = new Crypto();
const cryptoKeyPair = (await crypto.subtle.generateKey(
{
name: "ECDSA",
namedCurve: "P-256",
},
true,
[KeyUsage.SIGN]
));
const exportedKey = (await subtleCrypto.exportKey("jwk", cryptoKeyPair.privateKey));
Issue is not present with v1.1.6
For additional context i'm running NodeJS 12.22.1
Does this library have this problem?
I seem to be having problems verifying data+signature in the browser, using keys generated by this library. When I generate the keys in the browser it works fine, so is there a mismatch in ecdsa?
This algorithm is missing from this library. I would love to use it, but since AES-KW is required for JOSE for both ECDH-ES and PKES2 based key wrapping, I can't.
Would you accept a PR if I try to tackle this?
I'm implementing a JavaScript runtime agnostic WebSocket server. txiki.js does not support subtle. The only capability I need is Web Cryptography API subtle for digest()
function, e.g.,
// https://stackoverflow.com/a/77398427
async function digest(message, algo = "SHA-1") {
const { promise, resolve } = Promise.withResolvers();
const reader = new FileReader();
reader.onload = () => resolve(reader.result);
reader.readAsDataURL(
new Blob([
new Uint8Array(
await crypto.subtle.digest(
algo,
new TextEncoder().encode(
`${message}258EAFA5-E914-47DA-95CA-C5AB0DC85B11`,
),
),
),
]),
);
const result = await promise;
return result.split(",").pop();
}
I've fetched the repository and tried to bundle with
bun build ./src/index.ts --outfile=webcrypto.js --target=browser
yet have to substitute every Buffer
import for
import * as Buffer from "node:buffer";
where I'm not going to be using Node.js' Buffer
at all, rather I'll be using Uint8Array
and/or ArrayBuffer
and DataView
.
I am using your package in one of my subpackages in the browser with Angular. However when I call it, I am getting this error:
webcrypto.es.js:2233 Uncaught TypeError: crypto3.getCiphers is not a function
at new SubtleCrypto2 (webcrypto.es.js:2233:32)
at new Crypto2 (webcrypto.es.js:2276:23)
at node_modules/@transmute/web-crypto-key-pair/dist/web-crypto-key-pair.esm.js (web-crypto-key-pair.esm.js:814:27)
at __init (chunk-QPLMLQ3O.js?v=8ada0fd4:45:56)
at node_modules/@transmute/json-web-signature/dist/json-web-signature.esm.js (json-web-signature.esm.js:5:1)
at __init (chunk-QPLMLQ3O.js?v=8ada0fd4:45:56)
at node_modules/@cef-ebsi/verifiable-credential/dist/index.js (index.js:18:30)
at __require2 (chunk-QPLMLQ3O.js?v=8ada0fd4:48:50)
at node_modules/@cef-ebsi/verifiable-presentation/dist/index.js (index.js:20:33)
at __require2 (chunk-QPLMLQ3O.js?v=8ada0fd4:48:50)
I am using esbuild and added the polyfills like
import { polyfillNode } from 'esbuild-plugin-polyfill-node';
export default polyfillNode();
On the backend it's working fine, it seems to be a problem with the browser. Do you know if there needs to be an extra import?
node_modules/@peculiar/webcrypto/index.d.ts:4:10 - error TS2416: Property 'randomUUID' in type 'Crypto' is not assignable to the same property in base type 'Crypto'.
Type '() => string' is not assignable to type '() => `${string}-${string}-${string}-${string}-${string}`'.
Type 'string' is not assignable to type '`${string}-${string}-${string}-${string}-${string}`'.
4 public randomUUID(): string;
~~~~~~~~~~
Found 1 error in node_modules/@peculiar/webcrypto/index.d.ts:
And this is how the base Crypto
interface is defined in TS 5:
interface Crypto {
/** Available only in secure contexts. */
readonly subtle: SubtleCrypto;
getRandomValues<T extends ArrayBufferView | null>(array: T): T;
/** Available only in secure contexts. */
randomUUID(): `${string}-${string}-${string}-${string}-${string}`;
}
It all works after downgrading to TS 4.
The only fix I can think of would be using ${string}-${string}-${string}-${string}-${string}
from now on, but that'd then break on TS 4, so it'd be a breaking change.
Secure Curves in the Web Cryptography API
https://wicg.github.io/webcrypto-secure-curves/
depricated
(remove in the next major update)A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.