Ошибка типа: ключ не относится к типу 'CryptoKey' - PullRequest
1 голос
/ 25 февраля 2020

Я использую Node с библиотекой @ peicular / webcrypto для шифрования введенной мной строки; тем не менее, он выдает эту ошибку TypeError, но тот же код работает нормально в браузере Chrome. Я очень новичок в Node и Asyn c.

Вот код:

const { Crypto } = require("@peculiar/webcrypto");
const crypto = new Crypto();
const btoa = require('btoa');

const CC = "Hello World";
const b_size = CC.length;
P = new ArrayBuffer(b_size);
C = new Uint8Array(P);

function iKey() {
  return crypto.subtle.importKey(
    "jwk",{
      kty:"RSA",
      e:"AQAB",
      n:"gfJ-DTivOto0B1qvI9jGQgLvPvEkfVzbhf4-GM_XGrSyJRa1ASOZV89qpBIYDq8lwSwxibybvRqROhNavH6X_xQux9TAhDVBYZv8bH7pR4cfCLQrNvbpFRan3XBv7zeifGThyJGJ8R0BJTh4R4K9cu7kE48Ig1GO6iIx6emnYaQBhRUHsLfxfhQCwlHLraOXcP_RPM9TfZRO4dVHdRrdX1B60B6OqwU1ojRmo1oLiJCN6KjwMsYbSbYnflt_uyFUGxxBQE-1qnhBkarm10pgIgVDiSIn8XKQBxLg-Ao6cc7pXytp7Bd--g45OKHinRKaSP-Ub8g3S9g4LV2Qt8UZbQ",
      alg:"RSA-OAEP-256",
      ext:true
    },
    {
      name:"RSA-OAEP",
      hash: {name: "SHA-256"}
    },
    true,
    ["encrypt"]
  );
}

e_key = iKey();

for(i=0; i < b_size; ++i) {
  C[i] = CC.charCodeAt(i);
}


function crypt() {
  return crypto.subtle.encrypt(
    {
      name: "RSA-OAEP",
      hash: {name: "SHA-256"}
    },
    e_key, P
  ).then(function(encrypted){
    console.log(new Uint8Array(encrypted));
  }).catch(function(err){
    console.error(err);
  });
}

crypt();

1 Ответ

2 голосов
/ 25 февраля 2020

Причина, по которой это происходило, заключается в том, что к тому времени, когда crypt() работал, iKey() еще не завершился ..

Исправление состояло в том, чтобы переместить e_key = iKey() в функцию crypt() и делает crypt() функцию асинхронной c функцией , так что мы можем await для iKey() до sh перед тем, как попытаться использовать возвращаемые данные ..

крипта теперь выглядит так:

async function crypt() {
  let e_key = await iKey();

  return crypto.subtle.encrypt(
    {
      name: "RSA-OAEP",
      hash: {name: "SHA-256"}
    },
    e_key, P
  ).then(function(encrypted){
    console.log(new Uint8Array(encrypted));
  }).catch(function(err){
    console.error(err);
  });
}

Это полный файл:

const { Crypto } = require("@peculiar/webcrypto");
const crypto = new Crypto();
const btoa = require('btoa');

const CC = "Hello World";
const b_size = CC.length;
P = new ArrayBuffer(b_size);
C = new Uint8Array(P);

function iKey() {
  return crypto.subtle.importKey(
    "jwk",{
      kty:"RSA",
      e:"AQAB",
      n:"gfJ-DTivOto0B1qvI9jGQgLvPvEkfVzbhf4-GM_XGrSyJRa1ASOZV89qpBIYDq8lwSwxibybvRqROhNavH6X_xQux9TAhDVBYZv8bH7pR4cfCLQrNvbpFRan3XBv7zeifGThyJGJ8R0BJTh4R4K9cu7kE48Ig1GO6iIx6emnYaQBhRUHsLfxfhQCwlHLraOXcP_RPM9TfZRO4dVHdRrdX1B60B6OqwU1ojRmo1oLiJCN6KjwMsYbSbYnflt_uyFUGxxBQE-1qnhBkarm10pgIgVDiSIn8XKQBxLg-Ao6cc7pXytp7Bd--g45OKHinRKaSP-Ub8g3S9g4LV2Qt8UZbQ",
      alg:"RSA-OAEP-256",
      ext:true
    },
    {
      name:"RSA-OAEP",
      hash: {name: "SHA-256"}
    },
    true,
    ["encrypt"]
  );
}

/** COMMENTED THIS LINE OUT */
// e_key = iKey();

for(i=0; i < b_size; ++i) {
  C[i] = CC.charCodeAt(i);
}

async function crypt() {
  /** MOVED iKey INTO HERE */
  let e_key = await iKey();

  return crypto.subtle.encrypt(
    {
      name: "RSA-OAEP",
      hash: {name: "SHA-256"}
    },
    e_key, P
  ).then(function(encrypted){
    console.log(new Uint8Array(encrypted));
  }).catch(function(err){
    console.error(err);
  });
}

crypt();

Что возвращает:

// return
Uint8Array(256) [
   17,  88,  41, 189, 185, 200, 225,  96, 186, 155, 153, 212,
  207,  91, 203,   5,  38, 152,  19, 107, 182, 180, 210,  54,
  236, 153, 204, 112, 148,  65, 246, 208,  34,  90, 251,  40,
   64,  33, 175, 123,  84,  59, 249,  24, 125, 219,  65, 220,
    7, 186, 175, 204, 123,  41, 121, 143, 163, 100, 223, 180,
  167,  99,  19,  52, 117, 145, 215, 188, 226, 173, 237, 244,
  165, 101, 203, 104,  60,  26, 255, 181,  80, 185, 240, 162,
  156, 215, 212,  39,  13, 215,  51, 192, 167, 183,   4, 160,
  206,  92,  97,  84,
  ... 156 more items
]


Обновление:

Причина, по которой вы не можете использовать его в глобальной области видимости, заключается в том, что Node обрабатывает асинхронные c операции. С учетом вышесказанного у вас есть пара опций:

Опция 1

Вместо использования await для iKey() (который это просто syntacti c сахар для Обещаний) вы можете использовать с ним .then, а также превратить crypto в основанную на Promise функцию:

// code above removed for brevity

function crypt(key) {
  return new Promise((resolve, reject) => {
    crypto.subtle.encrypt(
      {
        name: "RSA-OAEP",
        hash: {name: "SHA-256"}
      },
      key, P
    ).then(encrypted => {
      resolve(new Uint8Array(encrypted));
    }).catch(err => {
      reject(err);
    });
  })
}

// Use it like:
iKey().then(e_key => {
  crypt(e_key) // <- we are now passing the key in as a param
    .then(enc => console.log(enc))
    .catch(err => console.error(err))
}).catch(error => {
  console.error(error);
})

Опция 2:

Обернуть все в asyn c немедленно вызванное выражение функции ..

(async () => {
  const e_key = await iKey();

  // also async now
  async function crypt() {
    return crypto.subtle.encrypt(
      {
        name: "RSA-OAEP",
        hash: {name: "SHA-256"}
      },
      e_key, P
    ).then(encrypted => {
      return new Uint8Array(encrypted);
    }).catch(err => {
      throw err;
    });
  }

  try {
    const enc = await crypt();
    console.log(enc);
  } catch (err) {
    console.error(err);
  }
})();

Существуют также библиотеки Promise, такие как BlueBird, которые вы можете использовать для сделать это проще, но это в значительной степени суть ..


Обновление 2:

Вот как вы можете использовать «глобальная функция» с обещанием.

const {
  Crypto
} = require("@peculiar/webcrypto");
const crypto = new Crypto();
const btoa = require('btoa');

const CC = "Hello World";
const b_size = CC.length;
P = new ArrayBuffer(b_size);
C = new Uint8Array(P);

function iKey() {
  return crypto.subtle.importKey(
    "jwk", {
      kty: "RSA",
      e: "AQAB",
      n: "gfJ-DTivOto0B1qvI9jGQgLvPvEkfVzbhf4-GM_XGrSyJRa1ASOZV89qpBIYDq8lwSwxibybvRqROhNavH6X_xQux9TAhDVBYZv8bH7pR4cfCLQrNvbpFRan3XBv7zeifGThyJGJ8R0BJTh4R4K9cu7kE48Ig1GO6iIx6emnYaQBhRUHsLfxfhQCwlHLraOXcP_RPM9TfZRO4dVHdRrdX1B60B6OqwU1ojRmo1oLiJCN6KjwMsYbSbYnflt_uyFUGxxBQE-1qnhBkarm10pgIgVDiSIn8XKQBxLg-Ao6cc7pXytp7Bd--g45OKHinRKaSP-Ub8g3S9g4LV2Qt8UZbQ",
      alg: "RSA-OAEP-256",
      ext: true
    }, {
      name: "RSA-OAEP",
      hash: {
        name: "SHA-256"
      }
    },
    true,
    ["encrypt"]
  );
}

/** COMMENTED THIS LINE OUT */
// e_key = iKey();

for (i = 0; i < b_size; ++i) {
  C[i] = CC.charCodeAt(i);
}

function crypt(key) { // <-- Notice we now pass in the key via a param
  return new Promise((resolve, reject) => {
    crypto.subtle.encrypt({
        name: "RSA-OAEP",
        hash: {
          name: "SHA-256"
        }
      },
      key, P
    ).then(function (encrypted) {
      resolve(new Uint8Array(encrypted));
    }).catch(function (err) {
      reject(err);
    });
  })
}

function someGlobalFunction(encryptedValue) {
  console.log("\r\n\r\nFROM GLOBAL FUNCTION:\r\n\r\n");
  console.log(encryptedValue);
  console.log("This is some global function");
  console.log("I am taking the encryped value as a param and doing something with it");
  console.log("For now, I just logged it to console..(see above)");
}

iKey().then(e_key => {
  crypt(e_key).then(encryped => { // <-- Notice we now pass in the key via a param
    someGlobalFunction(encryped);
  }).catch(error => {
    console.error(error);
  })
}).catch(err => {
  console.error(err);
});
...