Пример #1
0
        /// <summary>
        /// Указываем файл лицензии
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void DoRegister()
        {
            await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                pic.Source = Searching;
            });

            var removableDevices = KnownFolders.RemovableDevices;
            var externalDrives   = await removableDevices.GetFoldersAsync();

            foreach (var drive in externalDrives)
            {
                try
                {
                    StorageFile licfile = null;
                    licfile = await drive.GetFileAsync("wvlicense.lic");

                    if (licfile != null)
                    {
                        //файл выбран, выводим картинку что все в процессе
                        await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                        {
                            pic.Source = loading;
                        });

                        //инициализируем криптодвижок для проверки файла лицензии
                        string       RSAProvName = AsymmetricAlgorithmNames.RsaPkcs1;
                        StreamReader LicenseFile = File.OpenText(licfile.Path);
                        string       LicenseXML  = LicenseFile.ReadToEnd();
                        LicenseFile.Dispose();
                        AccLicense tmplic = Deserialize <AccLicense>(LicenseXML);
                        if (tmplic.IsLicenseValid())
                        {
                            //лицензия корректна
                            //выводим пользователю данные лицензии
                            await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                            {
                                userid.Foreground        = new SolidColorBrush(Colors.Green);
                                userid.Text              = tmplic.UserID;
                                regdatetime.Foreground   = new SolidColorBrush(Colors.Green);
                                regdatetime.Text         = tmplic.RegistrationDateTimeStr;
                                devcountlimit.Foreground = new SolidColorBrush(Colors.Green);
                                devcountlimit.Text       = tmplic.DeviceCountLimit.ToString();
                                statustext.Text          = "запрос регистрации...";
                            });

                            //данные для регистрации переводим в массив байт
                            byte[] tmphwidbytes  = Encoding.UTF8.GetBytes(GlobalVars.HardWareID);
                            byte[] tmpuidbytes   = Encoding.UTF8.GetBytes(tmplic.UserID);
                            byte[] tmpsplitbytes = new byte[3] {
                                254, 11, 254
                            };
                            byte[] tmpauthstrbytes = new byte[tmphwidbytes.Length + tmpuidbytes.Length + 3];
                            Array.Copy(tmphwidbytes, 0, tmpauthstrbytes, 0, tmphwidbytes.Length);
                            Array.Copy(tmpsplitbytes, 0, tmpauthstrbytes, tmphwidbytes.Length, tmpsplitbytes.Length);
                            Array.Copy(tmpuidbytes, 0, tmpauthstrbytes, tmphwidbytes.Length + tmpsplitbytes.Length, tmpuidbytes.Length);
                            //инициализируем криптодвижок для подписи и шифрования запроса
                            AsymmetricKeyAlgorithmProvider RSAEncryptProv = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(RSAProvName);
                            CryptographicKey      ServerPublicKey         = RSAEncryptProv.ImportPublicKey(Convert.FromBase64String(GlobalVars.ServerPublicKey).AsBuffer(), CryptographicPublicKeyBlobType.Capi1PublicKey);
                            string                strAlgName = HashAlgorithmNames.Sha512;
                            HashAlgorithmProvider objAlgProv = HashAlgorithmProvider.OpenAlgorithm(strAlgName);
                            CryptographicHash     objHash    = objAlgProv.CreateHash();
                            objHash.Append(tmpauthstrbytes.AsBuffer());
                            IBuffer authstringhash = objHash.GetValueAndReset();
                            byte[]  haashbytes     = authstringhash.ToArray();
                            //подписываем
                            byte[] tmpsignature = CryptographicEngine.SignHashedData(GlobalVars.ClientKeyPair, authstringhash).ToArray();
                            //шифруем
                            byte[] tmpauthstring = CryptographicEngine.Encrypt(ServerPublicKey, tmpauthstrbytes.AsBuffer(), null).ToArray();
                            //создаем объект запроса
                            WaterDeviceRegistrationRequest tmpreq = new WaterDeviceRegistrationRequest();
                            tmpreq.PublicKey           = GlobalVars.ClientKeyPair.ExportPublicKey(CryptographicPublicKeyBlobType.Capi1PublicKey).ToArray();
                            tmpreq.AuthorizationString = tmpauthstring;
                            tmpreq.AuthSignature       = tmpsignature;
                            //сериализуем в  XML
                            var xs  = new XmlSerializer(tmpreq.GetType());
                            var xml = new Utf8StringWriter();
                            xs.Serialize(xml, tmpreq);
                            //переводим в строку Base64
                            byte[] xmlbytes       = Encoding.UTF8.GetBytes(xml.ToString());
                            string xmlbytesbase64 = Convert.ToBase64String(xmlbytes);
                            //формируем запрос
                            Dictionary <string, string> data = new Dictionary <string, string>
                            {
                                { "RegistrationRequest", xmlbytesbase64 }
                            };
                            HttpFormUrlEncodedContent content = new HttpFormUrlEncodedContent(data);
                            while (true)
                            {
                                bool httpsuccess = false;
                                HttpResponseMessage httpResponse = new HttpResponseMessage();
                                //пробуем достучаться до сервера пока не опухнем
                                while (!httpsuccess)
                                {
                                    await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                                    {
                                        pic.Source      = loading;
                                        statustext.Text = "соединение с сервером...";
                                    });

                                    HttpClient httpClient = new HttpClient();
                                    Uri        requestUri = new Uri("https://" + tmplic.ServerEndPoint + GlobalVars.REGISTRATION_PATH);
                                    //отправляем на сервер
                                    httpResponse = await httpClient.PostAsync(requestUri, content);

                                    int delayvalue;
                                    try
                                    {
                                        //все нормально
                                        httpResponse.EnsureSuccessStatusCode();
                                        httpsuccess = true;
                                    }
                                    catch
                                    {
                                        //ошибка, пауза 1 минута, потом новая попытка
                                        await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                                        {
                                            pic.Source      = Waiting;
                                            statustext.Text = "Ошибка соединения, следующая попытка через 01:00";
                                        });

                                        delayvalue = 60;
                                        while (delayvalue > 0)
                                        {
                                            Task.Delay(1000).Wait();
                                            delayvalue--;
                                            await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                                            {
                                                pic.Source      = Waiting;
                                                statustext.Text = "Ошибка соединения, следующая попытка через " + (delayvalue / 60).ToString().PadLeft(2, '0') +
                                                                  ":" + (delayvalue % 60).ToString().PadLeft(2, '0');
                                            });
                                        }
                                    }
                                }
                                //обрабатываем ответ от сервера
                                string resp      = httpResponse.Content.ReadAsStringAsync().GetResults();
                                byte[] respbytes = Convert.FromBase64String(resp);
                                string respxml   = Encoding.UTF8.GetString(respbytes);
                                //создаем объект ответа
                                WaterDeviceRegistrationResponse regresp = Deserialize <WaterDeviceRegistrationResponse>(respxml);
                                //выводим пользователю сообщение от сервера
                                await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                                {
                                    regresponse.Text = regresp.AuthResponse;
                                });

                                if (regresp.AuthResponse.StartsWith("SUCCESS"))
                                {
                                    //вычисляем хеш открытого ключа клиента для проверки подписи
                                    strAlgName = HashAlgorithmNames.Sha512;
                                    objAlgProv = HashAlgorithmProvider.OpenAlgorithm(strAlgName);
                                    objHash    = objAlgProv.CreateHash();
                                    objHash.Append(tmpreq.PublicKey.AsBuffer());
                                    IBuffer ClientPublicKeyHashBuffer = objHash.GetValueAndReset();
                                    //подпись лицензии
                                    byte[]  SignatureBytes  = Convert.FromBase64String(regresp.Signature);
                                    IBuffer SignatureBuffer = SignatureBytes.AsBuffer();
                                    AsymmetricKeyAlgorithmProvider RSAVerifyProv = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithmNames.RsaSignPkcs1Sha512);
                                    ServerPublicKey = RSAVerifyProv.ImportPublicKey(Convert.FromBase64String(GlobalVars.ServerPublicKey).AsBuffer(), CryptographicPublicKeyBlobType.Capi1PublicKey);
                                    bool res = CryptographicEngine.VerifySignatureWithHashInput(ServerPublicKey, ClientPublicKeyHashBuffer, SignatureBuffer);
                                    if (res)
                                    {
                                        //подпись корректна, сохраняем ее в файл
                                        string signfilename = ApplicationData.Current.LocalFolder.Path + "\\" + GlobalVars.HardWareID + ".002";
                                        File.WriteAllBytes(signfilename, respbytes);
                                        //показываем пользователю, что все ОК
                                        await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                                        {
                                            pic.Source      = OK;
                                            statustext.Text = "OK";
                                        });

                                        return;
                                    }
                                    else
                                    {
                                        //подпись некорректна
                                        await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                                        {
                                            pic.Source      = Error;
                                            statustext.Text = "Регистрация закончилась неудачно";
                                        });

                                        return;
                                    }
                                }
                                if (regresp.AuthResponse == "OK_PENDING")
                                {
                                    await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                                    {
                                        pic.Source      = Waiting;
                                        statustext.Text = "Подтверждение, проверка через 05:00";
                                    });

                                    int delayvalue = 300;
                                    while (delayvalue > 0)
                                    {
                                        Task.Delay(1000).Wait();
                                        delayvalue--;
                                        await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                                        {
                                            statustext.Text = "Подтверждение, проверка через " + (delayvalue / 60).ToString().PadLeft(2, '0') + ":" + (delayvalue % 60).ToString().PadLeft(2, '0');
                                        });
                                    }
                                }
                            }
                        }
                        else
                        {
                            //Лицензия недействительна либо файл поврежден
                            await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                            {
                                pic.Source      = Error;
                                statustext.Text = "Лицензия недействительна";
                            });

                            return;
                        }
                    }
                }
                catch /*(DirectoryNotFoundException ex)*/
                {
                }
                //catch (FileNotFoundException ex)
                //{

                //}
            }
            await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                pic.Source      = Error;
                statustext.Text = "Ошибка: файл лицензии не найден";
            });
        }