2016-12-07 2 views
0

Я работаю над реализацией hybrid cryptosystem для проекта, который включает в себя большое количество межплатформенной защищенной сетевой связи. В этом случае стороны связи работают .NET и Java, поэтому я использую предоставленные криптосистемные структуры из каждого стека соответственно.Проблема обмена симметричными ключами с использованием RSA с кодированным размером больше размера блока

Я могу успешно сгенерировать ключевые пары одинакового размера (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), которая слишком велика для дешифрования с использованием моего 4096-битного ключа в соответствии с моей криптосистемой Java (javax.crypto.IllegalBlockSizeException: Data must not be longer than 512 bytes). Если это так, почему криптосистема .NET дает мне вывод в 513 байт с помощью OAEP, если он не может быть расшифрован с таким размером?

Ниже приведена реализация шифрования .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 использует тот же логический размер, как и выше с тем же KeySize):

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; 

есть ли проблема с моей реализацией?

ответ

0

Похоже, что на самом деле это была проблема с this question. Генерирование открытого ключа в системе Java имело начальный ноль в модуле BigInteger. Решается путем отсечения первого байта.

Смежные вопросы