1

I need to encrypt some text in the browser to be stored server side. After a little research I decided to use the SubtleCrypto API. I created the the crypto key using the following code:

window.crypto.subtle
        .generateKey(
            {
                name: "RSA-OAEP",
                modulusLength: 4096,
                publicExponent: new Uint8Array([1, 0, 1]),
                hash: "SHA-256",
            },
            true,
            ["encrypt", "decrypt"]
        )

My initial testing was successful but later I discovered that any text longer than 446 bytes is failing. Which looks like to be expected according to this answer. I am no crypto expert so what should I do to encrypt larger amounts of data (low megabytes). Choose a different algorithm, or split the data in chunks etc?

  • 4
    You should use Hybrid-Encryption where Encrypt with AES and transmit the encryption key with RSA. Do you really need RSA? Have you ever consider libsodium or age library – kelalaka May 23 '21 at 18:30
  • 2
    We're working on a readlist for new comers. You may check out this link to learn more about something relevant to your goal. – DannyNiu May 24 '21 at 02:15
  • 1
    RSA encryption is useful when the encryption and the decryption are done by different entities. In your case the browser encrypts the data. Where will it be decrypted? (If the server stores the data but does not decrypt it, that's irrelevant. What matters is who will decrypt.) – Gilles 'SO- stop being evil' May 24 '21 at 12:31
  • I am working on a zero knowledge server. So the server side will not do any decryption or know the key. The key will be stored in the browser, with backup options for the user. So the only place where the data and key are together is the users' browser. – Bahadır Yağan May 24 '21 at 16:08

1 Answers1

4

RSA can not directly encrypt large data. You need to generate a random key for a symmetric cipher (secure random), encrypt the large data with this key using a secure mode (e.g GCM). encrypt the key with your RSA public key, prepend encrypted key to encrypted data. store.

This is just for understanding of what goes on, you should look for a library which does as much of this together as possible from a reputable source, start with libsodium which I believe has a pure JS implementation.

Meir Maor
  • 11,835
  • 1
  • 23
  • 54
  • Thanks for this great explanation. SubtleCrypto is a web api implemented by all browser vendors. The standard supports four symmetric algorithms: RSA-OAEP, AES-CTR, AES-CBC, AES-GCM. So I should have read some more before choosing the first one on the list :) – Bahadır Yağan May 24 '21 at 16:03
  • I shouldn't have said RSA is symmetric. What I meant was the choice of algorithms that are for encryption and decryption. From this list: https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto#supported_algorithms – Bahadır Yağan May 24 '21 at 17:37