Шифрование между настольным приложением и сервером — C # для переполнения стека

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

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

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

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

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

15

Решение

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

Использование 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");

C #

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

Другие решения

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

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

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

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

РЕДАКТИРОВАТЬ:

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

11

По вопросам рекламы [email protected]