Я работаю над реализацией 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;
есть ли проблема с моей реализацией?