МИНИСТЕРСТВО ОБРАЗОВАНИЯ РЕСПУБЛИКИ БЕЛАРУСЬ
Учреждение образования
«Гомельский государственный технический университет
имени П.О.Сухого»
Факультет автоматизированных и информационных систем
Кафедра «Информационные технологии»
направление специальности 1-40 01 02-01 «Информационные системы и
технологии в проектировании и производстве»
ОТЧЕТ
по лабораторной работе №6 по теме:
«Разработка клиент-серверных приложений с использованием
WEB-средств на основе протокола HTTPs»
По дисциплине: «Программирование сетевых приложений»
Выполнил: студент гр. ИТ-32
Принял: преподаватель
Гомель
2014
Цель работы: разработать игру Bomberman с использованием web-средств на основе протокола HTTPs.
Краткие теоретические сведения
HTTPS – расширение протокола HTTP, поддерживающий шифрование. Данные, передаваемые по протоколу HTTP упаковываются в криптографический протокол SSL или TLS. В отличие от HTTP, для HTTPS по умолчанию используется TCP-порт 443.
Принцип работы
HTTPS не является отдельным протоколом. Это обычный HTTP, работающий через шифрованные транспортные механизмы SSL и TLS. Он обеспечивает защиту от атак, основанных на прослушивании сетевого соединения — от снифферских атак и атак типа man-in-the-middle при условии, что будут использоваться шифрующие средства и сертификат сервера проверен и ему доверяют.
По умолчанию HTTPS URL использует 443 TCP-порт (для незащищённого HTTP — 80). Чтобы подготовить веб-сервер для обработки https-соединений, администратор должен получить и установить в систему сертификат для этого веб-сервера. Сертификат состоит из 2 частей (2 ключей) — public и private. Public-часть сертификата используется для зашифрования трафика от клиента к серверу в защищённом соединении, private-часть — для расшифрования полученного от клиента зашифрованного трафика на сервере. После того как пара ключей приватный/публичный сгенерированы, на основе публичного ключа формируется запрос на сертификат в Центр сертификации, в ответ на который ЦС высылает подписанный сертификат. ЦС, при подписывании проверяет клиента, что позволяет ему гарантировать что держатель сертификата является тем, за кого себя выдаёт (обычно это платная услуга).
Существует возможность создать такой сертификат, не обращаясь в ЦС. Такие сертификаты могут быть созданы для серверов, работающих под Unix, с помощью таких утилит, как ssl-ca от OpenSSL или gensslcert от SuSE. Подписываются такие сертификаты этим же сертификатом и называются самоподписанными (self-signed). Без проверки сертификата каким-то другим способом (например, звонок владельцу и проверка контрольной суммы сертификата) такое использование HTTPS подвержено атаке man-in-the-middle.
Эта система также может использоваться для аутентификации клиента, чтобы обеспечить доступ к серверу только авторизованным пользователям. Для этого администратор обычно создаёт сертификаты для каждого пользователя и загружает их в браузер каждого пользователя. Также будут приниматься все сертификаты, подписанные организациями, которым доверяет сервер. Такой сертификат обычно содержит имя и адрес электронной почты авторизованного пользователя, которые проверяются при каждом соединении, чтобы проверить личность пользователя без ввода пароля.
В HTTPS для шифрования используются ключи длиной 40, 56, 128 или 256 бит. Лишь старые версии браузеров используют 40-битные ключи (IE версий до 4.0), что связано с экспортными ограничениями в США. Длина ключа 40 бит не является сколько-нибудь надёжной. Многие современные сайты требуют использования новых версий браузеров, поддерживающих шифрование с длиной ключа 128 бит, с целью обеспечить достаточный уровень безопасности. Такое шифрование значительно затрудняет злоумышленнику поиск паролей и другой личной информации.
Приложение А
(Листинг программы сервера)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.IO;
using System.Collections;
namespace BombermanServerCSVersion
{
class ServerHelper
{
static StreamWriter sw;
static X509Certificate serverCertificate = null;
static List<SslStream> sslStreams;
static List<string> packs;
public const int bombCode = 5;
public static int playerCount { get; set; }
public static int deadCount { get; set; }
public static int totalCount { get; set; }
List<Socket> clientList;
List<int> clientCodes;
public static int[, ,] matrix ={{{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0}},
{{0,0,0,0,0,0},{1,0,0,0,0,0},{0,0,0,0,0,0},{1,0,0,0,0,0},{0,0,0,0,0,0},{1,0,0,0,0,0},{0,0,0,0,0,0},{1,0,0,0,0,0},{0,0,0,0,0,0},{1,0,0,0,0,0},{0,0,0,0,0,0},{1,0,0,0,0,0},{0,0,0,0,0,0}},
{{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0}},
{{0,0,0,0,0,0},{1,0,0,0,0,0},{0,0,0,0,0,0},{1,0,0,0,0,0},{0,0,0,0,0,0},{1,0,0,0,0,0},{0,0,0,0,0,0},{1,0,0,0,0,0},{0,0,0,0,0,0},{1,0,0,0,0,0},{0,0,0,0,0,0},{1,0,0,0,0,0},{0,0,0,0,0,0}},
{{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0}},
{{0,0,0,0,0,0},{1,0,0,0,0,0},{0,0,0,0,0,0},{1,0,0,0,0,0},{0,0,0,0,0,0},{1,0,0,0,0,0},{0,0,0,0,0,0},{1,0,0,0,0,0},{0,0,0,0,0,0},{1,0,0,0,0,0},{0,0,0,0,0,0},{1,0,0,0,0,0},{0,0,0,0,0,0}},
{{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0}}};
public unsafe static void RunServer(string certificate)
{
serverCertificate = X509Certificate.CreateFromCertFile(certificate);
sslStreams = new List<SslStream>();
packs = new List<string>();
TcpListener listener = new TcpListener(IPAddress.Any, 8080);
listener.Start();
deadCount=0;
playerCount=0;
while (sslStreams.Count < totalCount)
{
//Console.WriteLine("Waiting for a client to connect...");
TcpClient client = listener.AcceptTcpClient();
SslStream sslStream = new SslStream(
client.GetStream(), false);
sslStreams.Add(sslStream);
try
{
sslStream.AuthenticateAsServer(serverCertificate,
false, SslProtocols.Tls, true);
/* DisplaySecurityLevel(sslStream);
DisplaySecurityServices(sslStream);
DisplayCertificateInformation(sslStream);
DisplayStreamProperties(sslStream);*/
sslStream.ReadTimeout = System.Threading.Timeout.Infinite;
sslStream.WriteTimeout = System.Threading.Timeout.Infinite;
}
catch (AuthenticationException e)
{
//Console.WriteLine("Exception: {0}", e.Message);
if (e.InnerException != null)
{
// Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
}
//Console.WriteLine("Authentication failed - closing the connection.");
sslStream.Close();
client.Close();
return;
}
//Console.WriteLine("Client connected");
Thread clientThr = new Thread(delegate() { RunRecv(playerCount); });
clientThr.Start();
Thread.Sleep(200);
playerCount++;
}
}
public static void SendInfoGlobal()
{
string message = ProcessMatrixToString(matrix);
foreach (var stream in sslStreams)
WriteMessage(stream, Encoding.ASCII.GetBytes(message.ToCharArray()));
}
public static byte[] ReadMessage(SslStream sslStream)
{
byte[] buffer = new byte[1024];
sslStream.Read(buffer, 0, 1024);
//var charArr = Encoding.ASCII.GetChars(buffer);
//StringBuilder str = new StringBuilder();
//str.Append(charArr, 0, 1024);
//string convertedString = str.ToString();
/*byte[] data = new byte[36];
for (int i = 79, k = 0; k < 36; i++, k++)
{
data[k] = buffer[i];
}*/
/*
sw.Write("Received: " + Encoding.ASCII.GetChars(buffer).ToString());
sw.WriteLine();
*/
//string[] responseLines = message.Replace("\r", "").Split('\n');
//byte[] data = Encoding.ASCII.GetBytes(responseLines[4].ToCharArray(), 0, 36);
return buffer;
}
public static void WriteMessage(SslStream sslStream, byte[] msg)
{
string message = null;
message = "POST / HTTP/1.0\r\nContent-Length: " + msg.Length + "\r\n" +
"Content-Type: application/octet-stream\r\n\r\n";
StringBuilder data = new StringBuilder();
data.Append(Encoding.ASCII.GetChars(msg), 0, msg.Length);
string fullRequest = message + data.ToString();
byte[] fullMsg = new byte[1024];
byte[] requestBytes = Encoding.ASCII.GetBytes(fullRequest.ToCharArray());
for (int i = 0; i < requestBytes.Length; i++)
{
fullMsg[i] = requestBytes[i];
}
/*
sw.Write("Sended: " + fullRequest);
sw.WriteLine();
*/
sslStream.Write(fullMsg, 0, 1024);
sslStream.Flush();
}
public static string ProcessMatrixToString(int[, ,] matrix)
{
string data = "";
for (int i = 0; i < 7; i++)
for (int j = 0; j < 13; j++)
for (int k = 0; k < 6; k++)
{
data += matrix[i, j, k];
}
return data;
}
public static void Badabum(object param)
{
Thread.Sleep(2000);
Position pos = (Position)param;
for (int i = -1; i <= 1; i++)
for (int k = 1; k < 6; k++)
{
if ((pos.y + i) >= 0 && (pos.y + i) < 7 && (pos.x) >= 0 && (pos.x) < 13)
if (matrix[pos.y + i, pos.x, k] > 0)
{
if (matrix[pos.y + i, pos.x, k] < bombCode && matrix[pos.y + i, pos.x, k] > 0)
deadCount++;
//Map.mtr[pos->y+i][pos->x][k]=0;
matrix[pos.y + i, pos.x, k] = 0;
}
if ((pos.y) >= 0 && (pos.y) < 7 && (pos.x + i) >= 0 && (pos.x + i) < 13)
if (matrix[pos.y, pos.x + i, k] > 0)
{
if (matrix[pos.y, pos.x + i, k] > 0 && matrix[pos.y, pos.x + i, k] < bombCode)
deadCount++;
//Map.mtr[pos->y][pos->x+i][k]=0;
matrix[pos.y, pos.x + i, k] = 0;
}
}
SendInfoGlobal();
}
public static int ParseResponse(string responseString)
{
string[] responseLines = responseString.ToString().Replace("\r", "").Split('\n');
var contentLengthString = responseLines[1].Split(' ')[1];
var requestLength = Convert.ToInt32(contentLengthString);
int data = Convert.ToInt32(responseLines[4]);
return data;
}
public static void RunRecv(int code)
{
Position point = GetPosition(code+1);
matrix[point.y, point.x, code + 1] = code + 1;
while (playerCount < totalCount) { }
while(true)
{
var msg=ReadMessage(sslStreams[code]);
var charsArr=Encoding.ASCII.GetChars(msg,0,1024);
StringBuilder message=new StringBuilder();
message=message.Append(charsArr,0,1024);
string strCode=message.ToString();
int keyCode=ParseResponse(strCode);
ProcessEnterKey(keyCode, ref point, code+1);
SendInfoGlobal();
if(isDead(code+1))
{
byte[] writingMessage = new byte[1024];
deadCount++;
writingMessage = Encoding.ASCII.GetBytes("9");
WriteMessage(sslStreams[code], writingMessage);
Thread.Sleep(-1);
}
else
{
if(totalCount-deadCount<=1)
{
byte[] writingMessage = new byte[1024];
writingMessage = Encoding.ASCII.GetBytes("8");
WriteMessage(sslStreams[code], writingMessage);
Thread.Sleep(-1);
}
}
}
}
public static void ProcessEnterKey(int key, ref Position point, int code)
{
if (matrix[point.y, point.x, code] != 0)
switch (key)
{
//d
case 275:
if ((point.x + 1) < 13 && matrix[point.y, point.x + 1, 0] != 1 && matrix[point.y, point.x + 1, bombCode] != bombCode)
{
matrix[point.y, point.x, code] = 0;
matrix[point.y, point.x + 1, code] = code;
point.x = point.x + 1;
}
break;
//a
case 276:
{
if ((point.x - 1) >= 0 && matrix[point.y, point.x - 1, 0] != 1 && matrix[point.y, point.x - 1, bombCode] != bombCode)
{
matrix[point.y, point.x, code] = 0;
matrix[point.y, point.x - 1, code] = code;
point.x = point.x - 1;
}
}
break;
//s
case 274:
{
if ((point.y + 1) < 7 && matrix[point.y + 1, point.x, 0] != 1 && matrix[point.y + 1, point.x, bombCode] != bombCode)
{
matrix[point.y, point.x, code] = 0;
matrix[point.y + 1, point.x, code] = code;
point.y = point.y + 1;
}
}
break;
//w
case 273:
if ((point.y - 1) >= 0 && matrix[point.y - 1, point.x, 0] != 1 && matrix[point.y - 1, point.x, bombCode] != bombCode)
{
matrix[point.y, point.x, code] = 0;
matrix[point.y - 1, point.x, code] = code;
point.y = point.y - 1;
}
break;
default:
matrix[point.y, point.x, bombCode] = bombCode;
Position bombPos = new Position();
bombPos.x = point.x;
bombPos.y = point.y;
Thread bombThr = new Thread(delegate() { Badabum(bombPos
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.