我正在为涉及大量跨平台安全网络通信的项目实施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密码系统给我一个带有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;
我的实施有问题吗?