Я пытаюсь использовать веб-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?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я потратил довольно много времени, борясь с этой ошибкой, и теперь я уверен, что могу дать вам (и всем остальным) несколько хороших советов по этому поводу.
Вы передаете «pkcs8» в качестве формата методу importKey, но если вы импортируете ПУБЛИЧНЫЙ ключ, формат, скорее всего, будет «spki» (SubjectPublicKeyInfo), специальным форматом для открытых ключей, в то время как «pkcs8» должен быть используется для ЧАСТНЫХ ключей. Это подводит нас к следующему пункту:
Откуда у тебя этот ключ? Если вы экспортируете открытый ключ с помощью OpenSSL cli (openssl rsa -pubout -in priv.pem -out pub.pem), то вы получаете ключ в формате "spki" (по умолчанию).
Вы должны передать ["зашифровать"] в качестве параметра "использования" в importKey (вместо пустого массива), если вы импортируете ПУБЛИЧНЫЙ ключ, в противном случае вы получите одну из следующих ошибок: "SyntaxError: Cannot create a ключ, использующий указанное использование ключа» (неправильное использование, указанное для ключа) или «InvalidAccessError: key.usages не разрешает эту операцию» (пустой массив использований). Здесь следует помнить, что открытые ключи можно использовать только для ["шифрования"] и закрытые ключи для ["расшифровки"]. Я не пытался импортировать пары ключей, но, насколько я понимаю, вы должны передать «pkcs8» в качестве формата и [«зашифровать», «расшифровать»] для использования.
Даже если вы настроите все вышеперечисленное правильно, вы все равно можете получить неприятную «Uncaught (in promise): DataError», для меня это было из-за несоответствия формата, я передал ключ в формате PKCS # 1 RSAPublicKey с параметр "спки". Поэтому вам, вероятно, следует начать с проверки вашего ключа, чтобы получить от него точные данные о формате и алгоритме.
Надеюсь, это поможет кому-то. Иван
Это действительно ужасно, что нужно заглянуть в двоичный формат, прежде чем понять, как его анализировать. Как это сделать?
Как я узнаю, что ключ, который я передаю, имеет правильный формат?