Tengo una aplicación ReactJS que debería poder verificar firmas con una clave pública RSA dada, como Web Crypto API, lo hace con sutil e import_key, etc. ¿Alguien sabe si existe tal biblioteca o cómo usar Web Crypto API en reaccionar directamente? Busqué mucho, pero no pude encontrar un ejemplo de trabajo para mí. Tal vez me perdí algo.
Probé antes la biblioteca @trust/webcrypto y la instalé con npm.
Este es el código que probé antes:
const crypto = require('@trust/webcrypto'); function base64decode(str) { let buffer = Buffer.from(str, 'base64'); return new Uint8Array(buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength)); } function importRsaPublicKey(pem) { const binaryDer = base64decode(pem); return crypto.subtle.importKey( "pkcs8", binaryDer, { name: "RSA-PSS", hash: "SHA-256", }, true, ["verify"] ); } La clave pública RSA se proporciona como una cadena base64 codificada en formato ASN.1 DER. Como ejemplo: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAimHHeNG9QnA7aMSjefJzMKfP...4XqwIDAQAB
Mi primer problema ya es importarlo correctamente. La firma quizás ya esté resuelta, cuando tengo una biblioteca de trabajo.
Cuando pruebo el código anterior, aparece el siguiente error en mi aplicación ReactJS: Unhandled Rejection (Error): Cannot find module '../algorithms/RSA-PSS'
Busqué el problema y parece que no puedo usarlo en reaccionar, por eso pregunté si alguien conoce una biblioteca que esté trabajando en reaccionar para importar una clave pública RSA y pueda verificar un mensaje firmado con un determinado firma.
La segunda biblioteca que probé fue @peculiar/webcrypto , pero parece que tampoco funciona.
El código que probé:
const { Crypto } = require("@peculiar/webcrypto"); const crypto = new Crypto(); function importRsaPublicKey(pem) { const binaryDer = base64decode(pem); return crypto.subtle.importKey( "pkcs8", binaryDer, { name: "RSA-PSS", hash: "SHA-256", }, true, ["verify"] ); } Esto genera el error de: Unhandled Rejection (Error): Data does not match to PrivateKeyInfo ASN1 schema.
La clave pública definitivamente está en codificación ASN.1 DER, pero es una clave pública y no una clave privada. No necesito la clave privada en mi configuración.
@Topaco mencionó que para usar una clave pública tengo que usar el formato spki . Eso resuelve el problema con la importación de la clave pública. Este código resuelve mi problema.
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 importRsaPublicKey(pem) { const binaryDerString = atob(pem); const binaryDer = str2ab(binaryDerString); return crypto.subtle.importKey( "spki", binaryDer, { name: "RSASSA-PKCS1-v1_5", hash: "SHA-256", }, true, ["verify"] ); } Usé el algoritmo RSASSA-PKCS1-v1_5 ya que no requiere sal.