【发布时间】: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