Пример #1
0
        private static String CryptRequestParser(String data, NskdSession session)
        {
            String response = null;

            // дешифрование запроса
            Byte[] encryptedBytes = Convert.FromBase64String(data);
            Byte[] plainBytes     = session.Decrypt(encryptedBytes);
            String package        = Encoding.UTF8.GetString(plainBytes);

            // разбор запроса
            try
            {
                // пока не разбор запроса, а только выполнение входа и регистрация пользователя
                RequestPackage p         = new RequestPackage(package);
                String         userToken = (string)p.GetParameterValueByName("userId");
                session.Update(userToken);
            }
            catch (Exception ex) { Console.WriteLine(ex.Message); }

            if (response != null)
            {
                // шифрование ответа
                plainBytes     = Encoding.UTF8.GetBytes(response);
                encryptedBytes = session.Encrypt(plainBytes);
                data           = Convert.ToBase64String(encryptedBytes);
            }
            return(package);
        }
Пример #2
0
        private static HttpWebResponse ProcessIncomingRequestToProtectedSite(HttpListenerContext context, SiteInf siteInf)
        {
            HttpListenerRequest incomingRequest  = context.Request;
            HttpWebResponse     incomingResponse = null;

            // GET - create session, or POST - download session
            if (incomingRequest.HttpMethod == "GET") // ! разобраться с HEAD
            {
                // Запросы типа GET могут быть к защищённому сайту (за ccs или js)
                // или могут быть к странице Login. Те которые к Login перехватываем
                // и отправляем ответ прямо из файлов которые есть на прокси. Кроме того, если
                // запрос без адреса или к странице Login, то создаём и регистрируем новую сессию.
                String      userAddress = null;
                NskdSession session     = null;
                switch (incomingRequest.Url.AbsolutePath)
                {
                case "/":
                case "/login/login.html":
                    userAddress = context.Request.RemoteEndPoint.Address.ToString();
                    session     = new NskdSession(userAddress);
                    RsaParameters ps          = session.Rsa.ExportParameters();
                    String        sessionId   = session.SessionId;
                    String        rsaModule   = Convert.ToBase64String(ps.Module);
                    String        rsaExponent = Convert.ToBase64String(ps.Exponent);
                    server.SendLoginPage(context, sessionId, rsaModule, rsaExponent);
                    break;

                case "/login/login.css":
                    server.SendFile(context, @"Login\Login.css");
                    break;

                case "/login/login.js":
                    server.SendFile(context, @"Login\Login.js");
                    break;

                case "/scripts/cryptico/cryptico.min.js":
                    server.SendFile(context, @"Scripts\Cryptico\cryptico.min.js");
                    break;

                case "/scripts/nskd/nskd.js":
                    server.SendFile(context, @"Scripts\Nskd\Nskd.js");
                    break;

                default:
                    // если запрос типа GET не перехвачен, то перенаправляем его клиенту
                    incomingResponse = siteInf.Client.GetResponse(context);
                    break;
                }
            }
            else if (incomingRequest.HttpMethod == "POST")
            {
                incomingResponse = ProcessPost(incomingRequest, context, siteInf);
            }
            else  // все остальные кроме GET и POST. ! разобраться с HEAD
            {
                incomingResponse = siteInf.Client.GetResponse(context);
            }
            return(incomingResponse);
        }
Пример #3
0
        public static NskdSession GetById(String sessionId)
        {
            NskdSession session = new NskdSession();

            session.SessionId = sessionId;
            // загружаем данные сессии
            DataSet sessionDataSet = Data.Db.Session.Get(sessionId);

            //Console.WriteLine(sessionDataSet.Tables.Count.ToString());
            session.Csp = new CryptServiceProvider();
            if (sessionDataSet.Tables.Count > 0)
            {
                DataTable dt0 = sessionDataSet.Tables[0];
                if (dt0.Rows.Count > 0)
                {
                    DataRow dr = dt0.Rows[0];
                    session.UserId = (dr["user_id"] != DBNull.Value) ? (Int32)dr["user_id"] : 0;
                    if (dr["crypt_key"] != DBNull.Value)
                    {
                        session.CryptKey = Convert.FromBase64String((String)dr["crypt_key"]);
                    }
                    else // Это первый запрос с зашифрованным ключом. Надо восстановить параметры RSA.
                    {
                        if (sessionDataSet.Tables.Count > 1)
                        {
                            DataTable dt1 = sessionDataSet.Tables[1];
                            if (dt1.Rows.Count > 0)
                            {
                                dr = dt1.Rows[0];
                                RsaParameters ps = new RsaParameters();
                                ps.P        = Convert.FromBase64String(dr["p"] as String);
                                ps.Q        = Convert.FromBase64String(dr["q"] as String);
                                ps.Module   = Convert.FromBase64String(dr["module"] as String);
                                ps.Exponent = Convert.FromBase64String(dr["exponent"] as String);
                                ps.D        = Convert.FromBase64String(dr["d"] as String);
                                session.Rsa = new Rsa();
                                session.Rsa.ImportParameters(ps);
                            }
                        }
                    }
                }
            }
            return(session);
        }
Пример #4
0
        private static Int32 LoadCryptKeyFromRequestDataToSession(String data, Int32 readerPointer, NskdSession session)
        {
            int b64EncryptedKeyMessageLength = data.IndexOf("\r\n", readerPointer) - readerPointer;

            if (b64EncryptedKeyMessageLength > 0)
            {
                // есть только первый раз
                String b64EncryptedKeyMessage = data.Substring(readerPointer, b64EncryptedKeyMessageLength);
                Byte[] encryptedKeyMessage    = Convert.FromBase64String(b64EncryptedKeyMessage);
                session.CryptKey = session.Rsa.DecryptMessage(encryptedKeyMessage, true);
            }
            return(b64EncryptedKeyMessageLength);
        }
Пример #5
0
        private static HttpWebResponse ProcessPost(HttpListenerRequest incomingRequest, HttpListenerContext context, SiteInf siteInf)
        {
            HttpWebResponse incomingResponse = null;
            String          response         = null;

            // Если запросы типа POST, то все их перенаправляем клиенту.
            // Здесь надо поймать первый запрос с общим ключём для шифрования.
            switch (incomingRequest.Url.AbsolutePath)
            {
            case "/":     // это запрос от страницы Login - надо потом добавить проверку

                // сессия уже есть, в потоке зашифрованный запрос
                NskdSession  session = null;
                String       data    = null;
                MemoryStream ms1     = new MemoryStream();
                MemoryStream ms2     = new MemoryStream();
                incomingRequest.InputStream.CopyTo(ms1);
                ms1.Position = 0;
                ms1.CopyTo(ms2);
                ms1.Position = 0;
                ms2.Position = 0;
                using (var sr = new StreamReader(ms1, Encoding.UTF8))
                {
                    data = sr.ReadToEnd();
                }
                if (!String.IsNullOrWhiteSpace(data))     // поток не пустой - расшифровка
                {
                    //Console.WriteLine("ProcessPost(): поток не пустой - расшифровка");
                    // возможно два варианта:
                    // 1. Это первый запрос после GET.
                    //    В нем есть <sessionId + \r\n + зашифрованный_rsa_common_key + \r\n + data>
                    // 2. Это не первый запрос после GET.
                    //    В нем <sessionId + \r\n + data>
                    // Отличить можно по наличю общего ключа.
                    Int32 sessionIdLength = data.IndexOf("\r\n");
                    if (sessionIdLength > 0)
                    {
                        Int32  readerPointer = 0;
                        String sessionId     = data.Substring(readerPointer, sessionIdLength);
                        readerPointer += sessionIdLength;
                        readerPointer += 2;     // 0d 0a
                        session        = NskdSession.GetById(sessionId);
                        //Console.WriteLine("ProcessPost(): session.SessionId " + session.SessionId);
                        // проверяем общий ключ
                        if (session.CryptKey == null)
                        {
                            // Общего ключа ещё нет. Значит он должен быть в запросе, зашифрованный RSA.
                            readerPointer += LoadCryptKeyFromRequestDataToSession(data, readerPointer, session);
                            readerPointer += 2;       // \r\n
                        }
                        if (session.CryptKey != null) // или загрузился из базы или только что создан из запроса
                        {
                            data     = data.Substring(readerPointer);
                            response = CryptRequestParser(data, session);
                            if (response.Length > 0)
                            {
                                ms2 = new MemoryStream();
                                //Byte[] buff = Encoding.UTF8.GetBytes(response);
                                //ms2.Write(buff, 0, buff.Length);
                            }
                        }
                    }
                }
                incomingResponse = siteInf.Client.GetResponse(context, session.SessionId, ms2);
                break;

            default:
                incomingResponse = siteInf.Client.GetResponse(context);
                break;
            }
            return(incomingResponse);
        }