Javascript RSA-OAEP 不适用于任意输入长度

Javascript RSA-OAEP does not work on arbitrary input lengths

我正在尝试使用 SubtleCrypto 加密 javascript (firefox) 中的字符串。问题在于,加密仅适用于短输入。一旦字符串 (testdata) 超过 190 个字符,它将因 OperationError 而失败。 为什么 SubtleCrypto 会这样,我该如何解决?

代码:

function str2ab(str) {
  var encoder = new TextEncoder('utf-8');
  return encoder.encode(str);
}

function ab2str(buf) {
  var decoder = new TextDecoder('utf-8');
  return decoder.decode(buf);
}

var keypair;
var algorithmKeyGen = {
  name: 'RSA-OAEP',
  modulusLength: 2048,
  publicExponent: new Uint8Array([1,
    0,
    1
  ]), // Equivalent to 65537
  hash: {
    name: 'SHA-256'
  }
};
var crypter = window.crypto.subtle;

function encrypt(buffer) {
  return crypter.encrypt(algorithmKeyGen, keypair.publicKey, buffer).then(
    function(data) {
      alert(ab2str(data));
    },
    function(error) {
      alert(error);
    }
  );
}

var testdata = "aasasadasdaasasadasdaasazzzzzzzzzzzzzzzzzzzzuuuuuuuuuuuuuuuuuuuuuuuzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzuuuuudddsdfssssssssssdddddddddddzzzzzzzzzzzzzzzzzzzzzzzzzzzzzppppppggppppppppppppppppssssstt"

crypter.generateKey(algorithmKeyGen, true, [
  'sign',
  'encrypt',
  'decrypt',
  'verify',
  'deriveKey'
]).then(function(res) {
  keypair = res;
  encrypt(str2ab(testdata));
}, console.error.bind(console, 'Unable to generate a key'));

经过一番研究,我发现您的问题可能有以下原因:

浏览器特定:

  • 错误的 Firefox 版本。该库支持 v34,并且兼容性级别可能取决于您使用的浏览器版本。确保你有正确的版本:

https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/encrypt

加密数据时:

  • 您的 normalizedAlgorithm 计数器成员的长度不是 16 字节
  • normalizedAlgorithm 的长度成员为零或大于 128
  • 密钥生成失败

https://www.w3.org/TR/WebCryptoAPI/

考虑到这一点,我相信问题不在于您要加密的文本,而在于您如何调用该函数。

另一个可能的原因(虽然,我不会把钱花在上面)是加密一个很长的字符串会生成一个对浏览器来说太长的变量。查看此讨论:

  • Javascript maximum size for types?

RSA 不适用于批量加密。可以使用 RSA 加密的具体数据量取决于密钥大小和您使用的填充。

一个 2048 位密钥 允许 256 字节,其中 OAEP 填充 采用 42 字节,剩下大约 214 字节 用于加密数据。

通常您会使用 RSA 来加密对称密钥,然后使用该对称密钥来加密实际数据。通常称为 hybrid encryption.