Научно-образовательный IT-форум при КНИТУ-КАИ

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Научно-образовательный IT-форум при КНИТУ-КАИ » Задачи и вопросы » [+] Вопрос по применению классов NetworkStream и CryptoStream


[+] Вопрос по применению классов NetworkStream и CryptoStream

Сообщений 1 страница 3 из 3

1

ИСХОДНЫЕ ДАННЫЕ С КОДОМ ПРОГРАММ:

Сервер:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography;

namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
                TcpClient client = new TcpClient();
                client.Connect("localhost", 5001);
                NetworkStream stm = client.GetStream();
                SymmetricAlgorithm des = new DESCryptoServiceProvider();
                des.Key = Encoding.ASCII.GetBytes("12345678");
                des.IV = Encoding.ASCII.GetBytes("12345678");
                ICryptoTransform desencrypt = des.CreateEncryptor();
                CryptoStream cryptostream = new CryptoStream(stm,desencrypt,CryptoStreamMode.Write);
                byte[] readBuf = Encoding.Unicode.GetBytes(Console.ReadLine());
                cryptostream.Write(readBuf, 0, readBuf.Length);
                cryptostream.Close();
                stm.Close();
        }
    }
}


Клиент:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Net.Sockets;
using System.Security.Cryptography;

namespace streamCrypto
{
    class Program
    {
        static void Main(string[] args)
        {
            TcpListener listener = new TcpListener(5001);
            listener.Start();
            TcpClient tc = listener.AcceptTcpClient();
            NetworkStream stm = tc.GetStream();
            SymmetricAlgorithm des = new DESCryptoServiceProvider();
            des.Key = Encoding.ASCII.GetBytes("12345678");
            des.IV = Encoding.ASCII.GetBytes("12345678");
            ICryptoTransform desdecrypt = des.CreateDecryptor();
            CryptoStream cryptostream = new CryptoStream(stm, desdecrypt, CryptoStreamMode.Read);
            byte[] readBuf = new byte[100];
            cryptostream.Read(readBuf, 0, 100);
            Console.WriteLine(Encoding.Unicode.GetString(readBuf));
            cryptostream.Close();
            stm.Close();
        }
    }
}


ВОПРОС:
Почему если в коде клиентской части убрать строчку:

cryptostream.Close();

получаем информацию об ошибке:

Необработанное исключение: System.Security.Cryptography.CryptographicException:
Плохие данные.

   в System.Security.Cryptography.CryptographicException.ThrowCryptogaphicExcept
ion(Int32 hr)
   в System.Security.Cryptography.Utils._DecryptData(SafeKeyHandle hKey, Byte[]
data, Int32 ib, Int32 cb, Byte[]& outputBuffer, Int32 outputOffset, PaddingMode
PaddingMode, Boolean fDone)
   в System.Security.Cryptography.CryptoAPITransform.TransformFinalBlock(Byte[]
inputBuffer, Int32 inputOffset, Int32 inputCount)
   в System.Security.Cryptography.CryptoStream.Read(Byte[] buffer, Int32 offset,
Int32 count)
   в streamCrypto.Program.Main(String[] args) в C:\LANDWATERSUN\TEMP\streamCrypt
o\streamCrypto\Program.cs:строка 26

?

2

В этом случае клиент закрывает NetworkStream stm быстрее, чем отрабатывает  cryptostream.Write(readBuf, 0, readBuf.Length). Часть данных теряется.  cryptostream.Close() не только уничтожает объект, но еще и выполнят flush() для данных в потоке.
Следующий код клиента работает:

Код:
class Program
    {
        static void Main(string[] args)
        {
            TcpClient client = new TcpClient();
            client.Connect("localhost", 5001);
            NetworkStream stm = client.GetStream();
            SymmetricAlgorithm des = new DESCryptoServiceProvider();
            des.Key = Encoding.ASCII.GetBytes("12345678");
            des.IV = Encoding.ASCII.GetBytes("12345678");
            ICryptoTransform desencrypt = des.CreateEncryptor();
            CryptoStream cryptostream = new CryptoStream(stm, desencrypt, CryptoStreamMode.Write);
            byte[] readBuf = Encoding.Unicode.GetBytes(Console.ReadLine());
            cryptostream.Write(readBuf, 0, readBuf.Length);
            cryptostream.FlushFinalBlock();
            stm.Close();
        }
    }

3

Благодарю Роман за подробный ответ, закрепленный примером! :)


Вы здесь » Научно-образовательный IT-форум при КНИТУ-КАИ » Задачи и вопросы » [+] Вопрос по применению классов NetworkStream и CryptoStream