CryptoKey ArrayBuffer para base64 e Back

Fiquei me perguntando como resolver esse problema. Gero par de chaves RSA-OAEP usando a API WebCrypto, depois exporto a chave privada no pkcs8 a partir do par de chaves que exporta como ArrayBuffer e quero codificar esse ArrayBuffer na base64 para que eu possa armazená-lo como um PEM.

Neste exemplo de teste, estou exportando a chave como pkcs8 e importando esse pkcs8 de volta para o CryptoKey. O problema é que às vezes funciona e às vezes não.

Estes são os resultados do código: OBSERVAÇÃO: acontece apenas um desses estados não todos de uma vez. NOTA2: Este exemplo não contém prefixo e sufixo ----- BEGIN PRIVATE KEY -----. Estou codificando apenas a chave.

Caso1: URIErro não detectado (em promessa): URI malformado (…) b64DecodeUnicode @ try.php: 20b64toab @ try.php: 70wayBack @ try.php: 66 (função anônima) @ try.php: 56

Caso2: indefinido: 1 Não detectado (em promessa) DOMException

Caso3: OK - funciona todo o caminho de volta.

Não sei o que causa os erros, mas acho que tem algo a ver com a codificação base64. Como eu disse, às vezes a chave privada gera OK e às vezes não.

Muito obrigado por toda ajuda com antecedência.

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);
    });
}

questionAnswers(2)

yourAnswerToTheQuestion