1

Following code works fine when I encrypt 190 bytes or less. But if I try 191 or more, an exception is thrown. What is the right way of encrypting larger pieces of data?

async function go(size) {
  var { publicKey, privateKey } = await crypto.subtle.generateKey({
    name: "RSA-OAEP",
    modulusLength: 2048,
    publicExponent: new Uint8Array([1, 0, 1]),
    hash: "SHA-256",
  }, true, ["encrypt", "decrypt"])

  try {
    var res = await window.crypto.subtle.encrypt(
      { name: "RSA-OAEP" },
      publicKey,
      new Uint8Array(size),
    )

    console.log(`${size} - OK: ${res.byteLength}`)
  } catch (ex) {
    console.log(`${size} - ERROR: ${ex.constructor.name} ${ex}`)
  }
}

go(10)    // Ok
go(100)   // Ok
go(190)   // Ok
go(191)   // Error
go(200)   // Error
go(500)   // Error
Qwertiy
  • 19,681
  • 15
  • 61
  • 128
  • 3
    Well, why do you need to use RSA for encryption? We prefer hybrid encryption where the asymmetric cryptosystem is used for key exchange, transfer, and symmetric cryptosystem encryption is used to encrypt with the key.One can use RSA-KEM + AES-GCM( possibly with AES-GCM-SIV ) or DHKE-AES-GCM, DHKE-XChacha20-Poly1305 or ECIES. – kelalaka Nov 08 '21 at 17:34
  • @JuanMendes, your edit makes output in SO snippet messy and doesn't add anything to output in browser console (actually even replaces `OperationError` by repeating `DOMException`). – Qwertiy Nov 08 '21 at 17:37
  • @Qwertiy You can rollback away from his edit if you want. I just took a look at both versions... I can see why that edit was made, but yeah. – Brad Nov 08 '21 at 17:49
  • @kelalaka, actually it's protection from passive traffic listening (not from mitm) as by some reason we are forced to send data via pure http. Something [like that (in Russian only)](https://habr.com/ru/post/537498/). – Qwertiy Nov 08 '21 at 17:56
  • 1
    Well, my comment is still valid then, see [Maarten's answer on Cryptography](https://crypto.stackexchange.com/a/42100/18298) for the reason of the limit - padding. – kelalaka Nov 08 '21 at 18:01
  • Yes, the RSA payload is limited to the keysize - RSA overhead. It's not designed to encrypt large amounts of data, but rather to facilitate public/private keys. Use something else like AES or the schemes suggested by @kelalaka – gview Nov 08 '21 at 18:10
  • [RSA-KEM AES-GCM](https://crypto.stackexchange.com/a/77834/18298) – kelalaka Nov 08 '21 at 18:12
  • @Qwertiy Sorry, I thought people would want to know if there's anything relevant in the exception – Ruan Mendes Nov 08 '21 at 18:14
  • @kelalaka, I understand that the size is limited, but I expected automatic splitting into several blocks of valid size... It won't be very lage, in most cases it evens fits 190, but twice more would be more desired. – Qwertiy Nov 08 '21 at 18:16
  • @JuanMendes, unfortunately this was nothing - code is zero and message is empty. – Qwertiy Nov 08 '21 at 18:16
  • Increase the modulus size? In the end, one side will have slow description. ECDH-XChaCha20-Poly1305 is read for [JS](https://github.com/jedisct1/libsodium.js/) - I'm not responsible for anything about the library, just DuckDuckGo'd. – kelalaka Nov 08 '21 at 18:24

0 Answers0