/// <summary>
        /// Asymmetrically signs the hash of data.
        /// </summary>
        /// <param name="hash">The hash to sign.</param>
        /// <param name="signingPrivateKey">The private key used to sign the data.</param>
        /// <param name="hashAlgorithmName">The hash algorithm name.</param>
        /// <returns>
        /// The signature.
        /// </returns>
        public override byte[] SignHash(byte[] hash, byte[] signingPrivateKey, string hashAlgorithmName)
        {
            var signer          = this.GetSignatureProvider(this.AsymmetricHashAlgorithmName);
            var key             = signer.ImportKeyPair(signingPrivateKey.ToBuffer());
            var signatureBuffer = CryptographicEngine.SignHashedData(key, hash.ToBuffer());

            return(signatureBuffer.ToArray());
        }
        /// <summary>
        /// Sign using a non-default hash algorithm.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="sigHash"></param>
        /// <returns></returns>
        public ISignatureUnion SignData(byte[] data, TpmAlgId sigHash)
        {
            var rsaParams = PublicParms.parameters as RsaParms;

            if (rsaParams != null)
            {
                TpmAlgId sigScheme = rsaParams.scheme.GetUnionSelector();

                switch (sigScheme)
                {
                case TpmAlgId.Rsassa:
                {
                    if (sigHash == TpmAlgId.Null)
                    {
                        sigHash = (rsaParams.scheme as SigSchemeRsassa).hashAlg;
                    }
                    byte[]  digest    = CryptoLib.HashData(sigHash, data);
                    IBuffer sigBuffer = CryptographicEngine.SignHashedData(Key, CryptographicBuffer.CreateFromByteArray(digest));
                    byte[]  sig;
                    CryptographicBuffer.CopyToByteArray(sigBuffer, out sig);
                    return(new SignatureRsassa(sigHash, sig));
                }

                case TpmAlgId.Rsapss:
                {
                    Globs.Throw <ArgumentException>("SignData(): PSS scheme is not supported");
                    return(null);
                }
                }
                Globs.Throw <ArgumentException>("Unsupported signature scheme");
                return(null);
            }

            var eccParms = PublicParms.parameters as EccParms;

            if (eccParms != null)
            {
                if (eccParms.scheme.GetUnionSelector() != TpmAlgId.Ecdsa)
                {
                    Globs.Throw <ArgumentException>("Unsupported ECC sig scheme");
                    return(null);
                }
                if (sigHash == TpmAlgId.Null)
                {
                    sigHash = (eccParms.scheme as SigSchemeEcdsa).hashAlg;
                }
                byte[]  digest = CryptoLib.HashData(sigHash, data);
                IBuffer buf    = CryptographicEngine.SignHashedData(Key, CryptographicBuffer.CreateFromByteArray(digest));
                byte[]  sig;
                CryptographicBuffer.CopyToByteArray(buf, out sig);
                int len = sig.Length / 2;
                return(new SignatureEcdsa(sigHash, Globs.CopyData(sig, 0, len), Globs.CopyData(sig, len, len)));
            }

            // Should never be here
            Globs.Throw("VerifySignature: Unrecognized asymmetric algorithm");
            return(null);
        } // SignData()
Example #3
0
        public static ClientRequest EncodeRequestData(object DataObject)
        {
            ClientRequest res = new ClientRequest();

            try
            {
                var xs  = new XmlSerializer(DataObject.GetType());
                var xml = new Utf8StringWriter();
                xs.Serialize(xml, DataObject);
                byte[] xmlbytes = Encoding.UTF8.GetBytes(xml.ToString());
                //инициализируем криптодвижок для подписи
                string RSAProvName = AsymmetricAlgorithmNames.RsaPkcs1;
                string AESProvName = SymmetricAlgorithmNames.AesCbcPkcs7;
                SymmetricKeyAlgorithmProvider AESProv = SymmetricKeyAlgorithmProvider.OpenAlgorithm(AESProvName);
                IBuffer          keyMaterial          = CryptographicBuffer.GenerateRandom(32);
                CryptographicKey AESkey                       = AESProv.CreateSymmetricKey(keyMaterial);
                IBuffer          iv                           = CryptographicBuffer.GenerateRandom(16);
                byte[]           encrypteddatabytes           = CryptographicEngine.Encrypt(AESkey, xmlbytes.AsBuffer(), iv).ToArray();
                AsymmetricKeyAlgorithmProvider RSAEncryptProv = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(RSAProvName);
                CryptographicKey      ServerPublicKey         = RSAEncryptProv.ImportPublicKey(Convert.FromBase64String(GlobalVars.ServerPublicKey).AsBuffer(), CryptographicPublicKeyBlobType.Capi1PublicKey);
                byte[]                encryptedkeybytes       = CryptographicEngine.Encrypt(ServerPublicKey, keyMaterial, null).ToArray();
                byte[]                encryptedivbytes        = CryptographicEngine.Encrypt(ServerPublicKey, iv, null).ToArray();
                string                strAlgName              = HashAlgorithmNames.Sha512;
                HashAlgorithmProvider objAlgProv              = HashAlgorithmProvider.OpenAlgorithm(strAlgName);
                CryptographicHash     objHash                 = objAlgProv.CreateHash();
                objHash.Append(xmlbytes.AsBuffer());
                IBuffer xmlbyteshash = objHash.GetValueAndReset();
                byte[]  tmpsignature = CryptographicEngine.SignHashedData(GlobalVars.ClientKeyPair, xmlbyteshash).ToArray();
                res.Request   = Convert.ToBase64String(encrypteddatabytes);
                res.Signature = Convert.ToBase64String(tmpsignature);
                res.AData     = Convert.ToBase64String(encryptedkeybytes);
                res.BData     = Convert.ToBase64String(encryptedivbytes);
            }
            catch /*(Exception ex)*/
            {
                res = null;
            }
            return(res);
        }
Example #4
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 = "Ошибка: файл лицензии не найден";
            });
        }