CryptoKey ArrayBuffer a base64 y Back

Me preguntaba cómo resuelvo este problema. Genero el par de claves RSA-OAEP usando WebCrypto API, luego exporto la clave privada en pkcs8 desde el par de claves que se exporta como ArrayBuffer y quiero codificar este ArrayBuffer en base64 para poder almacenarlo como un PEM.

En este ejemplo de prueba, estoy exportando la clave como pkcs8 e importando esta pkcs8 de nuevo a CryptoKey. El problema es que a veces funciona y a veces no.

Estos son resultados del código: NOTA: Solo sucede uno de estos estados, no todos a la vez. NOTA2: Este ejemplo no contiene ----- BEGIN PRIVATE KEY ----- prefijo y sufijo Solo estoy codificando la clave.

Caso1: no capturado (en promesa) URIError: URI malformado (...) b64DecodeUnicode @ try.php: 20b64toab @ try.php: 70wayBack @ try.php: 66 (función anónima) @ try.php: 56

Caso2: indefinido: 1 Sin capturar (en promesa) DOMException

Caso 3: OK, funciona todo el camino de regreso.

No sé qué causa los errores, pero creo que tiene algo que ver con la codificación base64. Como dije algunas veces, la clave privada genera OK y otras no.

Muchas gracias por cada ayuda de antemano.

function b64EncodeUnicode(str) {
    return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) {
        return String.fromCharCode('0x' + p1);
    }));
}

function b64DecodeUnicode(str) {
    return decodeURIComponent(Array.prototype.map.call(atob(str), function(c) {
        return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
    }).join(''));
}

function addNewLines(str) {
    var finalString = '';
    for(var i=0; i < str.length; i++) {
        finalString += str.substring(0, 64) + '\n';
        str = str.substring(64);
    }

     return finalString;
}

window.crypto.subtle.generateKey(
    {
        name: "RSA-OAEP",
        modulusLength: 2048,
        publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
        hash: {name: "SHA-256"}
    },
    true,
    ["encrypt", "decrypt"]
).then(function(keyPair) {
    window.crypto.subtle.exportKey(
        "pkcs8",
        keyPair.privateKey
    ).then(function(exportedPrivateKey) {
        var byteArray = new Uint8Array(exportedPrivateKey);
        console.log(byteArray);
        var byteString = '';
        for(var i=0; i < byteArray.byteLength; i++) {
            byteString += String.fromCodePoint(byteArray[i]);
        }

        wayBack(addNewLines(b64EncodeUnicode(byteString)));
    });
});

function wayBack(pem) {
    var lines = pem.split('\n');
    var encodedString = '';
    for(var i=0; i < lines.length; i++) {
        encodedString += lines[i].trim();
    }
    b64toab(encodedString);
}

function b64toab(b64) {
    var byteString = b64DecodeUnicode(b64);
    console.log(byteString);
    var byteArray = new Uint8Array(byteString.length);
    for(var i=0; i < byteString.length; i++) {
        byteArray[i] = byteString.codePointAt(i);
    }
    console.log(byteArray);

    window.crypto.subtle.importKey(
        "pkcs8",
        byteArray,
        {
            name: "RSA-OAEP",
            hash: {name: "SHA-256"}
        },
        true,
        ["decrypt"]
    ).then(function(importedPrivateKey) {
        console.log(importedPrivateKey);
    });
}

Respuestas a la pregunta(2)

Su respuesta a la pregunta