【问题标题】:Issue exchanging symmetric keys using RSA with encoded size larger than block size使用编码大小大于块大小的 RSA 交换对称密钥的问题
【发布时间】:2016-12-07 03:42:05
【问题描述】:

我正在为一个涉及大量跨平台安全网络通信的项目实施hybrid cryptosystem。在这种情况下,通信方正在运行 .NET 和 Java,因此我分别使用每个堆栈提供的密码系统框架。

我可以在两个系统上成功生成相同大小(4096 位)的密钥对,并成功传输密钥并将它们加载到远程系统中,以便我可以在每个系统上使用远程系统的公钥进行加密机器。

然后我在两个系统上生成对称密钥和 IV,并尝试在两个系统之间交换对称密钥。 不幸的是,在我在自定义通信协议中对密钥和 IV 信息进行编码后,数据大于密钥大小(不是很多,通常在 600-1000 字节区域,但仍然超过我的密钥大小的 ~500 字节限制)。

我对此的解决方案是拆分数据,并在适当大小的块上运行 RSA 加密。但是,我不知道将块拆分成多大的大小,因为我听说过许多不同的公式,例如:

  • ((KEY_SIZE) / 8) - 11
  • ((KEY_SIZE) / 8) - 42

但是,每当我使用第一个块大小(((KEY_SIZE) / 8) - 11,即 501 字节)加密信息时,RSACryptoServiceProvider.Encrypt(byte[] data, bool fOAEP) 会引发 Bad Length! 错误。每当我使用第二个块大小 (((KEY_SIZE) / 8) - 42) 时,它都会成功处理该块,但它给了我 513 字节的输出(似乎 0-500 字节之间的任何输入都被填充到这个 513 字节值,我假设是OAEP 在做它的工作),根据我的 Java 密码系统(javax.crypto.IllegalBlockSizeException: Data must not be longer than 512 bytes),它太大而无法使用我的 4096 位密钥解密。如果是这种情况,如果 .NET 密码系统无法以这种大小解密,为什么 .NET 密码系统会给我一个带有 OAEP 的 513 字节输出?

我的 .NET RSA 加密实现低于 ._rsaProvider 已使用有效的远程公钥初始化。 RSA_BUFFER_SIZE 是相对于 KEY_SIZE(即 4096)的常数(如果 RSA_BUFFER_SIZE 为 501,则不起作用,但似乎适用于 496 及以下,如上所述):

        byte[] block;
        using (MemoryStream stream = new MemoryStream())
        {
            int read = 0;
            while (read < data.Length)
            {
                block = new byte[RSA_BUFFER_SIZE]; 
                int toRead = Math.Min(data.Length - read, block.Length);
                Buffer.BlockCopy(data, read, block, 0, toRead);
                read += toRead;
                byte[] decrypted = _rsaProvider.Encrypt(block, true);
                stream.Write(decrypted, 0, decrypted.Length);
            }
            return stream.ToArray();
        }

这是解密此信息的Java实现(RSA_BUFFER_SIZE使用与上面相同的逻辑大小和相同的密钥大小):

    byte[] block;
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    int read = 0;
    while (read < data.length) {
        block = new byte[RSA_BUFFER_SIZE];
        int toRead = Math.min(data.length - read, block.length);
        System.arraycopy(data, read, block, 0, toRead);
        read += toRead;
        output.write(_localAsymmetricCipher.doFinal(block));
    }
    byte[] ret = output.toByteArray();
    output.close();
    return ret;

我的实现有问题吗?

【问题讨论】:

    标签: java c# encryption cryptography rsa


    【解决方案1】:

    看起来它实际上与this question 是同一个问题。我在 Java 系统上生成的公钥在模数 BigInteger 中具有前导零。通过切断第一个字节解决。

    【讨论】:

      猜你喜欢
      • 2020-04-07
      • 1970-01-01
      • 2012-06-26
      • 1970-01-01
      • 2011-12-10
      • 1970-01-01
      • 2014-02-21
      • 1970-01-01
      • 2015-03-12
      相关资源
      最近更新 更多