简体   繁体   English

window.crypto.subtle.importkey 和签名问题

[英]window.crypto.subtle.importkey and sign issue

In typescript I have the following code to sign a message with the ecdsa method and the SHA-512 algorithm.在 typescript 中,我有以下代码使用 ecdsa 方法和 SHA-512 算法对消息进行签名。

const pem = "-----BEGIN PRIVATE KEY-----\nByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgUIcMiv/YpEgR1CKRsL6sS85BVo6lYft/S5nIjTlCHvihRANCAATykP7bc8\n-----END PRIVATE KEY-----"
    // fetch the part of the PEM string between header and footer
    const pemHeader = "-----BEGIN PRIVATE KEY-----";
    const pemFooter = "-----END PRIVATE KEY-----";
    const pemContents = pem.substring(pemHeader.length, pem.length - pemFooter.length);
    // base64 decode the string to get the binary data
    const binaryDerString = window.atob(pemContents);
    // convert from a binary string to an ArrayBuffer
    const binaryDer = this.str2ab(binaryDerString);

    return window.crypto.subtle.importKey(
      "pkcs8",
      binaryDer,
      {
        name: "RSA-PSS",
        hash: "SHA-512",
      },
      true,
      ["sign"]
    );
  }

I have this method to sign the message:我有这种方法来签署消息:

createSignature2(){

    let privateKey = this.importPrivateKey();
    console.log(privateKey)
    let data = this.str2ab("Test buffer")
  
    let sign = window.crypto.subtle.sign(
      {
          name: "ECDSA",
          hash: {name: "SHA-512"}, //can be "SHA-1", "SHA-256", "SHA-384", or "SHA-512"
      },
      privateKey, //from generateKey or importKey above
      data //ArrayBuffer of data you want to sign
  )
  .then(function(signature){
      //returns an ArrayBuffer containing the signature
      console.log(new Uint8Array(signature));
  })
  .catch(function(err){
      console.error(err);
  });
  }

I get an error:我得到一个错误:

Argument of type 'Promise<CryptoKey>' is not assignable to parameter of type 'CryptoKey'.
  Type 'Promise<CryptoKey>' is missing the following properties from type 'CryptoKey': algorithm, extractable, type, usages

What am I missing here?我在这里错过了什么?

Thank you,谢谢,

The key import is incorrect.密钥导入不正确。 RSA-PSS imports an RSA key (for a signing/verification with RSASSA-PSS as padding). RSA-PSS导入 RSA 密钥(用于使用 RSASSA-PSS 作为填充的签名/验证)。 However, for ECDSA it makes no sense to import an RSA key.但是,对于 ECDSA,导入 RSA 密钥没有任何意义。 RSA and ECDSA are completely different algorithms. RSA和ECDSA是完全不同的算法。 Instead of the RSA key, an EC key must be imported and thereby the EC curve must be specified.必须导入 EC 密钥而不是 RSA 密钥,因此必须指定 EC 曲线。
Regarding the posted key itself: As already mentioned in the comment, this does not correspond to any valid format and it represents neither an RSA nor an EC key.关于发布的密钥本身:正如评论中已经提到的,这不符合任何有效格式,它既不代表 RSA 也不代表 EC 密钥。
Another point is about the syntax used.另一点是关于使用的语法。 The code often applies then() , but also constructions where the await keyword is missing.该代码通常应用then() ,但也应用缺少await关键字的结构。 Here, either only async/await (in a correct way) or only then() should be used consistently (s. here for the difference).在这里,应该一致地只使用async/await (以正确的方式)或只使用then() (s. here for the difference)。
Furthermore, str2ab() is missing.此外,缺少str2ab()

The following code shows an example of importing an EC key including signing with ECDSA.以下代码显示了导入 EC 密钥的示例,包括使用 ECDSA 签名。 P-521 is used as curve. P-521用作曲线。 As private key a PEM encoded sample EC key in PKCS#8 format is applied.作为私钥,应用 PKCS#8 格式的 PEM 编码样本 EC 密钥。
In the code the async/await syntax is applied (because this is clearer in my opinion).在代码中应用了async/await语法(因为我认为这更清楚)。 str2ab() is taken from the WebCrypto API documentation. str2ab()取自 WebCrypto API 文档。 ab2str() is the inverse function to this. ab2str()是它的逆 function。 The signature is Base64 encoded for display:签名为 Base64 编码用于显示:

 (async () => { createSignature2(); // Fix: apply consistently async/await syntax async function createSignature2(){ const privateKey = await importPrivateKey(); console.log(privateKey) const data = str2ab("Test buffer") const sign = await window.crypto.subtle.sign({name: "ECDSA",hash: {name: "SHA-512"}}, privateKey, data); console.log(window.btoa(ab2str(sign))); } async function importPrivateKey() { const pem = `-----BEGIN PRIVATE KEY----- MIHuAgEAMBAGByqGSM49AgEGBSuBBAAjBIHWMIHTAgEBBEIA3G3l+QFixI4fD4zW lC9n7xnT/7MS4bm6Ge6KXPmesmy9AARSdysdhWLXq51hvd/4F4Rd+ZYWn8bdeN58 zOJdRAOhgYkDgYYABAGBW8V/nf4yXdePGpotIL8WNR1182yBdcztCpWQUkL9TOEy vhhnf8SwtRDglbjCBiVONw4+WjC3pRfo3yTmee+mEQE3peJArA1zOFz9WJZhigA9 aK3t8BUbisZ38C4jcRuGgaBYUvg3ndMdqZnsNdbcg7sKOM9szCUvzGWkIWn2l4lW zA== -----END PRIVATE KEY-----`; const pemHeader = "-----BEGIN PRIVATE KEY-----"; const pemFooter = "-----END PRIVATE KEY-----"; const pemContents = pem.substring(pemHeader.length, pem.length - pemFooter.length); const binaryDerString = window.atob(pemContents); const binaryDer = str2ab(binaryDerString); return await window.crypto.subtle.importKey("pkcs8", binaryDer,{name: "ECDSA",namedCurve: "P-521"}, true, ["sign"]); // Fix: import ECDSA key } function str2ab(str) { const buf = new ArrayBuffer(str.length); const bufView = new Uint8Array(buf); for (let i = 0, strLen = str.length; i < strLen; i++) { bufView[i] = str.charCodeAt(i); } return buf; } function ab2str(buf) { return String.fromCharCode.apply(null, new Uint8Array(buf)); } })();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM