【问题标题】:ECMAScript 8, async await, syntactical errors javascriptECMAScript 8,异步等待,语法错误 javascript
【发布时间】:2022-01-04 09:03:41
【问题描述】:

在函数链中使用多个 async() 会破坏我的函数。 有没有办法可以将Key2pkcs8() 包含在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 =&gt; console.log(Key2pkcs8[0], Key2pkcs8[1])); 按预期工作并返回 pri = [object CryptoKey] Promise { &lt;state&gt;: "fulfilled", &lt;value&gt;: undefined } Promise { &lt;state&gt;: "fulfilled", &lt;value&gt;: CryptoKey }

但是当使用 return pkcs8keyarray() 而不是 return Keyarray = [PriKey(), PubKey()]; 时,它会中断并返回 undefined

我原本打算让key2pkcs2 将密钥作为变量(公钥或私钥),然后在最后的数组中返回两者,类似于示例

【问题讨论】:

  • PriKeyPubKey 没有明确的 return,因此它们只会产生解析为 undefined 的承诺。另外,既然这是一个承诺,你应该await-ing 结果(或使用.then()

标签: javascript asynchronous promise ecmascript-2017


【解决方案1】:
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();
}

用法:

generateKey().then(Key2pkcs8 => console.log(Key2pkcs8 ));

如果你的外部 iife 是异步的,await 已经将异步流转换为同步,这意味着 getKeyPair(或我的 sn-p 中的 keyPair)在你调用其他函数时已经可用。

PubKeyPriKey 不需要是异步的,在这两种情况下你都不会返回任何东西。 Key2pkcs8 也没有返回任何内容,那么您究竟希望 await Key2pkcs8(PubKey()); 返回什么?理想情况下,如果您希望生成的 Promise 解析为 undefined 以外的其他内容,则所有这些函数都应该返回一些内容。上面的sn-p试试看,我没测试过。

【讨论】:

  • 我使用您的主题对我的帖子进行了一些编辑并尝试*使其更清晰,尽管如果没有 PubKeyPriKey 不异步,我无法运行任何东西
  • 如果你想让它们异步,你需要链接它们:PubKey(keyPair).then(keyPair =&gt; PriKey(keyPair)).then(keyPair =&gt; Key2pkcs8(keyPair)).then(Key2pkcs8 =&gt; printme(Key2pkcs8)).then(Key2pkcs8=&gt; /*do something with Key2pkcs8*/) 你需要再次添加 async 关键字并修改 printme 因为它不再需要等待 Key2pkcs8,它会收到它作为论据
【解决方案2】:

您的程序展示了对 Promise、async/await、加密模块和整个 javascript 的误解。

  • 仅当您想为绑定重新分配值时才使用let
  • 不要将函数重新分配给值,尤其是在很容易避免的地方
  • return Keyarray = ... 之类的语句正在泄漏全局变量,其行为可能与您的预期不同
  • 你不需要每次想await另一个异步值时都创建一个新的async函数
  • 您不能简单地console.log 私钥或公钥。根据exportKey 文档,它返回一个解析为ArrayBuffer 的promise,它是原始字节数据,没有字符串表示。
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
  ]
}

由于generateKey 正在返回[private, public] 的数组对,我们可以轻松地在您编写的其他异步函数中使用它们-

async function myfunction() {
  const [private, public] = await generateKey() // <- resolves pair
  // do something
}

.then 处理程序中将所有副作用移动到下游。调用者负责catching 错误。始终处理错误 -

myfunction().then(console.log).catch(console.error)

如果您不了解这些简单的事情,请不要尝试实施加密解决方案。您将 100% 出错,并引入漏洞,您和您的用户将遭受后果。

此答案中的代码未经测试,仅在此处突出显示我很容易看到的错误。不要逐字使用代码,也不要期望它直接将其复制/粘贴到您的项目中。我不明白您的要求或意图是什么,因此无法提出建议或提供其他建议。

有关滥用asyncawait 的更多信息,请参阅this related Q&A

【讨论】:

  • 对整个 javascript 的巨大误解” - 即使是真的,你也可能想稍微调低你的语言。此外,我会将免责声明放在答案的页脚中,而不是放在顶部
  • 感谢您的反馈,我调整了帖子。 @cubesareneat 返回值可能是您所期望的,很可能您并不打算泄漏全局变量。这种错误可能会将安全程序变成易受攻击的程序。如果您在控制台中看到undefined,那么您没有数组缓冲区。我很乐意帮助,我真诚地没有不尊重的意思。如果您还有其他问题,请随时提问
  • 似乎任何时候 await crypto.subtle.exportKey("pkcs8" 的使用次数都比我在尝试 consol.log 时得到 Uncaught (in promise) DOMException: Operation is not supported 时更多地使用 myfunction 中的任何一个返回值......但如果它只返回一个导出的 pkcs8 键,另一个没有 exportkey() 操作的值按预期工作并记录数组缓冲区...如果其中一种 exportkeys 格式是crypto.subtle.exportKey("raw",它甚至可以工作并返回 2 个数组缓冲区
  • @cubesareneat 我确实注意到,如果你 console.log(privateKey, publicKey) 只有私钥有 usages: ["deriveKey"] 而公钥有 usages: []。我对 ECDH 算法、基于 Web 的 crypto 模块或您提供修复的预期用途不够熟悉。
  • 我会回到你给我一个很好的起点的文档
猜你喜欢
  • 1970-01-01
  • 2018-07-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-10
  • 2018-07-29
  • 1970-01-01
  • 2019-03-01
  • 1970-01-01
相关资源
最近更新 更多