SubtleCrypto importKey из PEM

Я пытаюсь использовать веб-API SubtleCrypto в Ionic для шифрования данных с использованием открытого ключа. Я импортирую ключ в формате PEM, затем передаю его в window.crypto.subtle.importKey, а затем использую этот результат в window.crypto.subtle.encrypt

Похоже, что есть проблема с window.crypto.subtle.importKey — я получаю Uncaught (in promise): DataError, когда пытаюсь импортировать ключ.

В настоящее время я использую следующие методы для импорта ключа:

//Get the public key in CryptoKey format
let importedPublicKey = await window.crypto.subtle.importKey(
    "pkcs8",
    this.pemPublicToArrayBuffer(serverPublicKey),
    {
        name: "RSA-OAEP",
        hash: {name: "SHA-256"}
    },
    true,
    []
);

private pemPublicToArrayBuffer(pem) {
  var b64Lines = this.removeLines(pem);
  var b64Prefix = b64Lines.replace('-----BEGIN PUBLIC KEY-----', '');
  var b64Final = b64Prefix.replace('-----END PUBLIC KEY-----', '');

  return this.base64ToArrayBuffer(b64Final);
}

private base64ToArrayBuffer(b64) {
  var byteString = window.atob(b64);
  var byteArray = new Uint8Array(byteString.length);
  for (var i = 0; i < byteString.length; i++) {
    byteArray[i] = byteString.charCodeAt(i);
  }

  return byteArray;
}

Кто-нибудь знает, почему импорт ключа не работает с открытым ключом PEM?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
0
1 387
1

Ответы 1

Я потратил довольно много времени, борясь с этой ошибкой, и теперь я уверен, что могу дать вам (и всем остальным) несколько хороших советов по этому поводу.

  1. Вы передаете «pkcs8» в качестве формата методу importKey, но если вы импортируете ПУБЛИЧНЫЙ ключ, формат, скорее всего, будет «spki» (SubjectPublicKeyInfo), специальным форматом для открытых ключей, в то время как «pkcs8» должен быть используется для ЧАСТНЫХ ключей. Это подводит нас к следующему пункту:

  2. Откуда у тебя этот ключ? Если вы экспортируете открытый ключ с помощью OpenSSL cli (openssl rsa -pubout -in priv.pem -out pub.pem), то вы получаете ключ в формате "spki" (по умолчанию).

  3. Вы должны передать ["зашифровать"] в качестве параметра "использования" в importKey (вместо пустого массива), если вы импортируете ПУБЛИЧНЫЙ ключ, в противном случае вы получите одну из следующих ошибок: "SyntaxError: Cannot create a ключ, использующий указанное использование ключа» (неправильное использование, указанное для ключа) или «InvalidAccessError: key.usages не разрешает эту операцию» (пустой массив использований). Здесь следует помнить, что открытые ключи можно использовать только для ["шифрования"] и закрытые ключи для ["расшифровки"]. Я не пытался импортировать пары ключей, но, насколько я понимаю, вы должны передать «pkcs8» в качестве формата и [«зашифровать», «расшифровать»] для использования.

  4. Даже если вы настроите все вышеперечисленное правильно, вы все равно можете получить неприятную «Uncaught (in promise): DataError», для меня это было из-за несоответствия формата, я передал ключ в формате PKCS # 1 RSAPublicKey с параметр "спки". Поэтому вам, вероятно, следует начать с проверки вашего ключа, чтобы получить от него точные данные о формате и алгоритме.

Надеюсь, это поможет кому-то. Иван

Как я узнаю, что ключ, который я передаю, имеет правильный формат?

Gursimran Singh 30.11.2021 11:09

Это действительно ужасно, что нужно заглянуть в двоичный формат, прежде чем понять, как его анализировать. Как это сделать?

Henry Story 21.12.2021 21:05

Другие вопросы по теме