using more then one async()
in a chain in the function breaks my function.
Is there a way i can include Key2pkcs8()
inside generateKey()
?
async function generateKey() {
let getKeyPair = await crypto.subtle.generateKey(
{
name: "ECDH",
namedCurve: "P-384"
},
false,
["deriveKey"]
);
let PriKey = async() => {
let PriKey = await getKeyPair.privateKey;
console.log("pri = " PriKey);
return PriKey;
};
let PubKey = async() => {
let PubKey = await getKeyPair.publicKey;
console.log("pub = " PubKey);
};
let Key2pkcs8 = async(PriKey, PubKey) => {
let Key2pkcs8Pub = await crypto.subtle.exportKey("pkcs8", PubKey);
let Key2pkcs8Pri = await crypto.subtle.exportKey("pkcs8", PriKey);
return pkcs8keyarray = [Key2pkcs8Pub, Key2pkcs8Pri];
return Keyarray = [PriKey(), PubKey()]; // i want to put <return pkcs8keyarray()> here
};
generateKey().then(Key2pkcs8 => console.log(Key2pkcs8[0], Key2pkcs8[1]));
works as expected and returns pri = [object CryptoKey]
Promise { <state>: "fulfilled", <value>: undefined } Promise { <state>: "fulfilled", <value>: CryptoKey }
but when using return pkcs8keyarray()
instead of return Keyarray = [PriKey(), PubKey()];
it breaks and returns undefined
i had intended to have key2pkcs2
take a key as a variable (public or private key) and then return both in a array at the end similar to the example
CodePudding user response:
Your program demonstrates a misunderstanding of promises, async/await, the crypto module, and javascript as a whole.
- Use
let
only when you want to reassign values to a binding - Don't reassign functions to values, especially where it's easily avoidable
- Statements like
return Keyarray = ...
are leaking global variables and do not behave like you are probably expecting - You do not need to create a new
async
function every time you want toawait
another asynchronous value - You cannot simply
console.log
the private or public keys. Per the exportKey docs, it returns a promise that resolves to an ArrayBuffer which is raw byte data and does not have a string representation.
async function generateKey() {
const {privateKey, publicKey} = // <- get privateKey, publicKey
await crypto.subtle.generateKey(
{
name: "ECDH",
namedCurve: "P-384"
},
true,
["deriveKey"]
)
return [
await crypto.subtle.exportKey("pkcs8", privateKey), // <- export private
await crypto.subtle.exportKey("pkcs8", publicKey), // <- export public
]
}
Since generateKey
is returning an array pair of [private, public]
, we can easily use these in the other async functions you write -
async function myfunction() {
const [private, public] = await generateKey() // <- resolves pair
// do something
}
Move all side effects downstream in .then
handlers. Caller is responsible for catch
ing errors. Always handle errors -
myfunction().then(console.log).catch(console.error)
Do not try to implement cryptographic solutions if you do not understand these simple things. You will 100% get something wrong and you will introduce a vulnerability and you and your users will suffer the consequences.
Code in this answer is unttested and only here to highlight the mistakes I can readily see. Do not use the code verbatim and do not expect it to copy/paste it directly into your project. I do not understand what your requirements or intentions are and therefore cannot possibly make recommendations or offer other advice.
For more info on misuse of async
and await
, see this related Q&A.
CodePudding user response:
async function generateKey() {
let keyPair = await crypto.subtle.generateKey(
{
name: "ECDH",
namedCurve: "P-384"
},
false,
["deriveKey"]
);
let PriKey = (keyPair) => {
let PriKey = keyPair.privateKey;
console.log("pri = " PriKey);
return keyPair;
};
let PubKey = (keyPair) => {
let PubKey = keyPair.publicKey;
console.log("pub = " PubKey);
return keyPair;
};
let Key2pkcs8 = async(keyPair) => {
console.log("key = " keyPair);
let Key2pkcs8 = await crypto.subtle.exportKey("pkcs8", keyPair);
return Key2pkcs8;
};
let printme = async() => {
let printme = await Key2pkcs8(PubKey());
console.log(printme);
return printme;
};
return printme();
}
Usage:
generateKey().then(Key2pkcs8 => console.log(Key2pkcs8 ));
If your outer iife is async, await
will already convert async flow to sync, meaning getKeyPair
(or keyPair
in my snippet) will already be available by the time you call other functions.
PubKey
and PriKey
need not to be async, and in both cases you are not returning anything. Key2pkcs8
is not returning anything either, so what exactly do you want await Key2pkcs8(PubKey());
to return? Ideally all these functions should return something if you want the resulting Promise
to resolve to something other than undefined
. Give the above snippet a go, I did not test it.