簡體   English   中英

window.crypto.subtle.importkey 和簽名問題

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

在 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"]
    );
  }

我有這種方法來簽署消息:

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);
  });
  }

我得到一個錯誤:

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

我在這里錯過了什么?

謝謝,

密鑰導入不正確。 RSA-PSS導入 RSA 密鑰(用於使用 RSASSA-PSS 作為填充的簽名/驗證)。 但是,對於 ECDSA,導入 RSA 密鑰沒有任何意義。 RSA和ECDSA是完全不同的算法。 必須導入 EC 密鑰而不是 RSA 密鑰,因此必須指定 EC 曲線。
關於發布的密鑰本身:正如評論中已經提到的,這不符合任何有效格式,它既不代表 RSA 也不代表 EC 密鑰。
另一點是關於使用的語法。 該代碼通常應用then() ,但也應用缺少await關鍵字的結構。 在這里,應該一致地只使用async/await (以正確的方式)或只使用then() (s. here for the difference)。
此外,缺少str2ab()

以下代碼顯示了導入 EC 密鑰的示例,包括使用 ECDSA 簽名。 P-521用作曲線。 作為私鑰,應用 PKCS#8 格式的 PEM 編碼樣本 EC 密鑰。
在代碼中應用了async/await語法(因為我認為這更清楚)。 str2ab()取自 WebCrypto API 文檔。 ab2str()是它的逆 function。 簽名為 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