Шифрование между настольным приложением и сервером - С# на PHP


У меня есть приложение, разработанное на C#. Проще говоря, приложение отправляет данные и изображение на мой веб-сервер, который принимает все данные $_POST и обрабатывает их. Признаюсь, я не понимаю, как работает система безопасности. Я найму кого-нибудь с соответствующим опытом, чтобы сделать это, однако я бы даже не знал, что спросить у них на данный момент, как в некоторых принятых методах.

Я предполагаю, что это не так просто, как просто кодировать/декодировать данные в base64, и для этого требуется более высокий уровень шифрования. Веб-сервер будет иметь сертификацию HTTPS SSL(OV) в течение следующих нескольких недель, но мое ограниченное понимание заключается в том, что мне все еще нужна какая-то защита/шифрование при передаче данных с ПК пользователей на мой веб-сервер, чтобы кто-то не прослушивал передачу данных или что-то в этом роде.

Проще говоря, если я хочу обеспечить безопасность данных между пользователями и моим веб-сервером, каковы некоторые из наиболее распространенных или принятых методов для C# на PHP?

В данные поступают непосредственно из приложения на ПК пользователя на мой сервер, я контролирую исходный код для обоих, но я сам, а не разработчик, поэтому у меня нет технических знаний по этому вопросу.

Один разработчик C#, с которым я разговаривал, предложил симметричный/асимметричный алгоритм, но он не разработчик PHP, поэтому он не знает, может ли php взять эти данные и расшифровать их.

Author: user1547410, 2015-04-29

2 answers

Чтобы ответить на ваши дальнейшие вопросы, когда сервер выпущен и правильно настроен с хорошим сертификатом, вам больше ничего не нужно делать.

Использование HTTPS

HTTPS работает путем проверки сертификатов SSL с Центром сертификации (CA) во время первоначального рукопожатия. Центры сертификации, которые по сути представляют собой список подписей, используемых для проверки указанных сертификатов, обычно предварительно загружаются поставщиком операционной системы.

Предполагая, что ваш сервер имеет сертификат, выданный центром сертификации, все, что вам потребуется сделать, это перейти с использования HTTP на HTTPS при подключении. В библиотеке, которую вы используете, должен быть способ проверки SSL-сертификата сервера, если он не делает это автоматически за вас.

Нет никаких технических причин для того, чтобы вам приходилось шифровать все, что будет отправляться по протоколу HTTPS, при условии, что сертификат надежно зашифрован.

Кроме того, если вы хотите углубиться в мельчайшие детали того, как работает HTTPS, есть это очень хорошее сообщение об информационной безопасности, которое проливает немного света на внутреннюю работу протокола.

Чтобы ответить на ваш первоначальный вопрос

Для полноты картины.

PHP имеет расширение криптографии mcrypt, которое поддерживает различные алгоритмы и режимы работы шифра. Я собрал простой пример, используя дешифрование ключа AES 256/PBKDF-SHA1 (вместе с кодом C# для выполнения шифрования).

РЕДАКТИРОВАТЬ: Я бы хотел обратите внимание, что hash_pbkdf2 доступен только в PHP 5.5 и выше. Поддержка до 5.3 может быть добавлена с помощью этого изящного трюка.

PHP

function decode_aes($data, $key) // Decrypt custom format data string
{
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
    $salt_size = 16;

    $iv = substr($data, 0, $iv_size); // Init vector
    $salt = substr($data, $iv_size, $salt_size); // The salt
    $extact = substr($data, $iv_size + $salt_size); // This is the encrypted data

    $key = hash_pbkdf2("sha1", $key, $salt, 1000, 32, true); // Sets to use PBKDF-SHA1

    return mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $extact, MCRYPT_MODE_CBC, $iv); // Perform the decryption with the extracted sections
}

// As an example, I've included this.
$encryped = "zgCp2sSDs32Y8SOn8MYFCEjOJDeM4E3Y8Wx52A+iTFRk/1TJwMzkqmrB06bFu8dK";
echo decode_aes(base64_decode($encryped), "password");

С#

using System;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace AESExample
{
    class Program
    {
        static void Main(string[] args)
        {
            byte[] toEncrypt = Encoding.UTF8.GetBytes("Encrypted Text");
            byte[] key = Encoding.UTF8.GetBytes("password");
            String encrypted = Convert.ToBase64String(EncryptAES(toEncrypt, key));
        }

        public static byte[] EncryptAES(byte[] data, byte[] key)
        {
            using(RijndaelManaged algo = new RijndaelManaged())
            {
                algo.GenerateIV();
                algo.Mode = CipherMode.CBC;
                algo.Padding = PaddingMode.Zeros;

                byte[] saltBuffer = new byte[16];
                RNGCryptoServiceProvider saltGenerator = new RNGCryptoServiceProvider();
                saltGenerator.GetBytes(saltBuffer);

                Rfc2898DeriveBytes PBKDF2 = new Rfc2898DeriveBytes(key, saltBuffer, 1000);
                key = PBKDF2.GetBytes(32);

                ICryptoTransform cipher = algo.CreateEncryptor(key, algo.IV);

                using(MemoryStream ms = new MemoryStream())
                {
                    ms.Write(algo.IV, 0, algo.IV.Length);
                    ms.Write(saltBuffer, 0, saltBuffer.Length);
                    using(CryptoStream cs = new CryptoStream(ms, cipher, CryptoStreamMode.Write))
                    {
                        using(StreamWriter sw = new StreamWriter(cs))
                        {
                            sw.Write(Encoding.UTF8.GetString(data).ToCharArray());
                        }
                    }
                    return ms.ToArray();
                }
            }
        }
    }
}
 4
Author: Bryan Way, 2017-03-17 10:45:55

Похоже, вас беспокоит безопасность данных при передаче из клиентского приложения на сервер и наоборот. Как уже упоминалось в комментариях, в этом отношении будет достаточно HTTPS-соединения. Он автоматически выполняет шифрование/дешифрование для вас.

Чтобы обеспечить работу HTTPS-соединения, вы должны приобрести SSL-сертификат (Namecheap - это один веб-сайт, на котором вы можете его купить) и установить его на свой веб-сервер. Сертификат является автоматически устанавливается на локальном компьютере пользователя при первом подключении к серверу, и каждое последующее подключение выполняет проверку на наличие действительного сертификата. Таким образом, по сути, вы просто устанавливаете сертификат на сервер и вам не нужно беспокоиться об этом, пока вам не потребуется обновить свой сертификат. Просто убедитесь, что ваше клиентское приложение пытается подключиться к HTTPS-адресу вместо HTTP.

Если бы вы реализовали симметричное/асимметричное шифрование, это помогло бы с шифрование и дешифрование до и после передачи данных. Если вы зашифруете данные в своем клиентском приложении, вам придется расшифровать их на стороне сервера, когда вы их получите, и наоборот. Это обеспечит вам еще более надежную безопасность; однако, в зависимости от характера вашего приложения, может быть достаточно HTTPS-соединения.

Одним из моих личных проектов является клиентское приложение на C#, которое подключается к веб-серверу Ruby, которое я также написал. Я установил SSL-сертификат на свой веб-сервер Ruby, поэтому эти данные шифруются во время передачи. В моем случае передаваемые данные не содержат никаких пользовательских данных или персональных данных (Личной информации) и, следовательно, не представляют угрозы для безопасности, если внешняя сторона получит доступ к этой информации. Таким образом, я чувствовал, что использование шифрования до и после транзита не имеет смысла и не принесет никакой пользы конечному пользователю. Опять же, это зависит от характера вашего приложения и ожиданий ваших пользователей.

ИЗМЕНИТЬ:

Как мой упомянутый в комментариях, StartSSL предлагает бесплатные SSL-сертификаты.

 11
Author: Alexander, 2017-05-23 11:53:51