Почему функция шифрования WebCryptoAPI RSA-OAEP не может использовать ожидаемый максимальный размер фрагмента для данного размера ключа?

Я пытаюсь использовать crypto.subtle.encrypt для шифрования некоторых данных и столкнулся с проблемой из-за количества данных, которые я могу зашифровать за раз. Максимальный размер блока для 2048-битного ключа с использованием RSA-OAEP составляет 214 байт, как указано в ссылках crypto.stackexchange.com и stackoverflow.com, используя отношение maxChunkSizeInBytes = keySizeInBytes – 42.

Используя crypto.subtle.encrypt с 2048-битным ключом и алгоритмом RSA-OAEP, я могу зашифровать только 190 байт. Любая сумма меньше 190 байт работает нормально, а любая сумма выше 190 байт приводит к ошибке. Я не совсем уверен в типе ошибки (поскольку я не могу ее уловить), но я думаю, что это OperationError , ссылка developer.mozilla.org.

В показанном здесь примере TypeScript есть два фрагмента данных d1 и d2 размером 190 байт и 214 байт соответственно. Блок данных d1 шифруется нормально, а d2 нет.

const MSG_LEN_1 = 190;
const MSG_LEN_2 = 214;

const d1 = (window.crypto.getRandomValues(new Uint8Array(MSG_LEN_1))).buffer;
const d2 = (window.crypto.getRandomValues(new Uint8Array(MSG_LEN_2))).buffer;

let encData = async (data: ArrayBuffer) => {
    const key = await crypto.subtle.generateKey(
        {
            name: "RSA-OAEP",
            modulusLength: 2048,
            publicExponent: new Uint8Array([1, 0, 1]),
            hash: "SHA-256",
        },
        true,
        ["encrypt", "decrypt"]
    );
    const enc = await crypto.subtle.encrypt(
            {
              name: "RSA-OAEP"
            },
            key.publicKey,
            data
          );
    return enc;
};

encData(d1).then(
    (enc : ArrayBuffer) => {
        alert("Success working on d1");
    }
);

encData(d2).then(
    (enc : ArrayBuffer) => {
            alert("Success working on d2");
    }
);

При компиляции и запуске вышеуказанного TypeScript в Firefox и Chrome (путем включения в простую html-страницу) я заметил ошибку Uncaught (in promise) DOMException в консоли разработчика после первого предупреждения.

Есть ли что-то, что я упускаю при использовании crypto.subtle.encrypt или неправильно использую алгоритм RSA-OAEP?


person Nishit Joseph    schedule 18.05.2019    source источник
comment
Может быть, я использую неправильное отношение, должен ли я использовать maxChunkSizeInBytes = keySizeInBytes - hashSizeInBytes * 2 – 2, поэтому для 2048-битного ключа с хэшем SHA-256 это 2048/8-256/8*2-2=190 байта?   -  person Nishit Joseph    schedule 18.05.2019
comment
Именно, размер хэша SHA-256 составляет 256 бит/32 байта.   -  person pedrofb    schedule 18.05.2019


Ответы (1)


Используя формулу modulus size - 2 - 2*hash size, она работает правильно для SHA256 (32 байта). Кажется, вы применяете размер SHA1 (20 байт)

  • SHA256: 256 - 2 - 2*32 = 190

  • SHA1: 256 - 2 - 2*20 = 214

person pedrofb    schedule 18.05.2019
comment
Да, только что проверил пример с SHA-512, и максимальный размер был 126 байт. Спасибо! - person Nishit Joseph; 18.05.2019