Шифрование и дешифрование с помощью RSA OAEP

Я использую Web Crypto, а точнее эти примеры: https://github.com/diafygi/webcrypto-examples/#rsa-oaep

Моя основная цель - зашифровать строку своим открытым ключом и расшифровать ее своим закрытым ключом.

Шифрование с открытым ключом работает хорошо, но когда я пытаюсь расшифровать зашифрованную строку с помощью закрытого ключа, оно возвращает следующую ошибку: OperationError, а также пустую строку.

Я использую следующие функции:

function encryptDataWithPublicKey(data, key) {
    data = stringToArrayBuffer(data);
    return window.crypto.subtle.encrypt(
    {
        name: "RSA-OAEP",
        //label: Uint8Array([...]) //optional
    },
    key, //from generateKey or importKey above
    data //ArrayBuffer of data you want to encrypt
);
}


function decryptDataWithPrivateKey(data, key) {
    data = stringToArrayBuffer(data);
    return window.crypto.subtle.decrypt(
        {
            name: "RSA-OAEP",
            //label: Uint8Array([...]) //optional
        },
        key, //from generateKey or importKey above
        data //ArrayBuffer of data you want to encrypt
    );
}

function stringToArrayBuffer(str){
    var buf = new ArrayBuffer(str.length);
    var bufView = new Uint8Array(buf);
    for (var i=0, strLen=str.length; i<strLen; i++) {
        bufView[i] = str.charCodeAt(i);
    }
    return buf;
}

ОБНОВЛЕНИЕ

var data = "example";
encryptDataWithPublicKey(data, publicKey).then((result) => {
    var rdata = arrayBufferToString(result);
    return decryptDataWithPrivateKey(rdata, privateKey).then((result) => {
        var result = arrayBufferToString(result);
    });
});

function arrayBufferToString(str){
    var byteArray = new Uint8Array(str);
    var byteString = '';
    for(var i=0; i < byteArray.byteLength; i++) {
        byteString += String.fromCodePoint(byteArray[i]);
    }
    return byteString;
}

person urb    schedule 10.01.2017    source источник
comment
вы говорите, что шифруете данные, а затем расшифровываете их ... вы показали функции, которые это делают, но не показали как вы их используете - возможно, вы используете их неправильно (т. е. что вы делаете с возвращаемым значением из ваших функций шифрования / дешифрования)   -  person Jaromanda X    schedule 10.01.2017
comment
EncryptDataWithPublicKey работает хорошо, но я не могу расшифровать его с помощью другой функции. Я не понимаю почему.   -  person urb    schedule 10.01.2017
comment
да, вы уже сказали в вопросе ... но я попросил вас показать как вы используете свои функции, потому что я подозреваю, что вы делаете это неправильно, я не просил это тратить зря ваши время или что-нибудь   -  person Jaromanda X    schedule 10.01.2017
comment
@ Jaromanda X, разобрался и обновил вопрос.   -  person urb    schedule 10.01.2017
comment
Да, я чувствую, что проблема в преобразовании arrayBufferToString и stringToArrayBuffer ... но я не могу понять это   -  person Jaromanda X    schedule 10.01.2017
comment
зашифрованные данные обычно являются двоичными ... вы меняете это на строку и обратно на двоичную, вы можете вводить ошибки преобразования   -  person Jaromanda X    schedule 10.01.2017
comment
Большинство систем кодируют зашифрованный текст из необработанных байтов в шестнадцатеричную или в кодировку Base64 для обеспечения переносимости и стабильности (вы получите безопасную строку типа 54686973206973206120706c61696e74657874206d6573736167652e0a или VGhpcyBpcyBhIHBsYWludGV4dCBtZXNzYWdlLgo=). Затем просто декодируйте эту строку перед расшифровкой необработанных байтов.   -  person Andy    schedule 10.01.2017


Ответы (1)


Код, включенный в ваш вопрос, правильный, поэтому проблема будет в скрытой части. Я только что добавил window.crypto.subtle.generateKey в ваш код для генерации ключей RSA-OAEP и работает

Пожалуйста, посмотрите полный пример

function stringToArrayBuffer(str){
    var buf = new ArrayBuffer(str.length);
    var bufView = new Uint8Array(buf);
    for (var i=0, strLen=str.length; i<strLen; i++) {
        bufView[i] = str.charCodeAt(i);
    }
    return buf;
}

function arrayBufferToString(str){
    var byteArray = new Uint8Array(str);
    var byteString = '';
    for(var i=0; i < byteArray.byteLength; i++) {
        byteString += String.fromCodePoint(byteArray[i]);
    }
    return byteString;
}

function encryptDataWithPublicKey(data, key) {
    data = stringToArrayBuffer(data);
    return window.crypto.subtle.encrypt(
    {
        name: "RSA-OAEP",
        //label: Uint8Array([...]) //optional
    },
    key, //from generateKey or importKey above
    data //ArrayBuffer of data you want to encrypt
);
}


function decryptDataWithPrivateKey(data, key) {
    data = stringToArrayBuffer(data);
    return window.crypto.subtle.decrypt(
        {
            name: "RSA-OAEP",
            //label: Uint8Array([...]) //optional
        },
        key, //from generateKey or importKey above
        data //ArrayBuffer of data you want to encrypt
    );
}


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) {

    var data = "example";
    encryptDataWithPublicKey(data, keyPair.publicKey).then((result) => {
        var rdata = arrayBufferToString(result);
        return decryptDataWithPrivateKey(rdata, keyPair.privateKey).then((result) => {
            var result = arrayBufferToString(result);
            console.log(result);
        });
    });
}).catch (function (err){
    console.log(err);
});
person pedrofb    schedule 10.01.2017