要交换AES加密消息,我使用RSA为每条消息编码IV并将其发送到另一个客户端。这在我第一次发送消息时成功,但在发送第二条消息时失败。客户端无法解密带有OAEP填充错误的消息的IV。
这是我的代码:
writeAes(Encoding.UTF8.GetBytes("12345"), rmAes.Key, RSAprovider.ToXmlString(false)); // These are just some sample messages
writeAes(Encoding.UTF8.GetBytes("67890"), rmAes.Key, RSAprovider.ToXmlString(false));
public void writeAes(TcpClient client, byte[] writeBuffer, int offset, byte[] AESkey, string RSAXml) //Some of these arguments are optional
{
using (RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.KeySize = 128;
rijAlg.Key = AESkey;
rijAlg.GenerateIV();
// Send IV
using (RSACryptoServiceProvider RSAprovider = new RSACryptoServiceProvider(4096))
{
RSAprovider.PersistKeyInCsp = false;
RSAprovider.FromXmlString(RSAXml);
this.write(client, RSAprovider.Encrypt(rijAlg.IV, true));
logger.Trace("Sent AES IV:\n{0}", BitConverter.ToString(rijAlg.IV).Replace("-", ""));
}
// Send Rijndael-encrypted Message
CryptoStream csEncrypt = null;
try
{
ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);
csEncrypt = new CryptoStream(client.GetStream(), encryptor, CryptoStreamMode.Write);
csEncrypt.Write(writeBuffer, offset, writeBuffer.Length);
csEncrypt.FlushFinalBlock();
encryptor.Dispose();
}
finally
{
/*if (csEncrypt != null)
csEncrypt.Dispose();*/
// TODO: This needs to be disposed somehow but leave the NetworkStream open
}
}
}
接收:
logger.Debug("Got AES-Message:\n" + Encoding.UTF8.GetString(readAes(connectedClient, new byte[5], 0, aesKey, RSAprovider.ToXmlString(true))));
logger.Debug("Got AES-Message:\n" + Encoding.UTF8.GetString(readAes(connectedClient, new byte[5], 0, aesKey, RSAprovider.ToXmlString(true))));
public byte[] readAes(TcpClient client, byte[] readBuffer,int offset, byte[] AESkey, string RSAXml) //Some of these arguments are optional
{
using (RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.KeySize = 128;
rijAlg.Key = AESkey;
using (RSACryptoServiceProvider RSAprovider = new RSACryptoServiceProvider(4096))
{
RSAprovider.PersistKeyInCsp = false;
RSAprovider.FromXmlString(RSAXml);
rijAlg.IV = RSAprovider.Decrypt(this.read(client, new byte[512]), true); //This is where the error occurs on the second message
logger.Trace("Got AES IV:\n{0}", BitConverter.ToString(rijAlg.IV).Replace("-", ""));
}
CryptoStream cryptoStream = null;
try
{
ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);
cryptoStream = new CryptoStream(client.GetStream(), decryptor, CryptoStreamMode.Read);
int read = 0;
int error = 0;
while (read < readBuffer.Length)
{
int bytesRead = cryptoStream.Read(readBuffer, read, readBuffer.Length - read);
read += bytesRead;
if (bytesRead == 0 && read != error)
{
logger.Debug("Reached end of stream at {0}. Waiting for more data...", read);
error = read;
}
}
decryptor.Dispose();
return readBuffer;
}
finally
{
/*if (cryptoStream != null)
cryptoStream.Dispose();*/
// TODO: This needs to be disposed somehow but leave the NetworkStream open
}
}
}
我的猜测是,CryptoStream尝试解密的数据比读取的数据多,并且弄乱了IV,但我不知道我可以改变什么来解决这个问题。