Как правильно передать соль с клиента на сервер и обратно при шифровании? В качестве сервера использую ASP.NET WebApi 2.
В качестве клиента универсальное приложение на Windows 10
Везде используется NET.Framework 4.6
Данные пересылаются по http.
Для шифрования использую PCLCryptohttps://github.com/aarnott/pclcrypto
Ниже класс для шифрования:public static class Crypto
{
public static byte[] CreateSalt(uint lengthInBytes)
{
return WinRTCrypto.CryptographicBuffer.GenerateRandom(lengthInBytes);
}
public static byte[] CreateDerivedKey(string password, byte[] salt, int keyLengthInBytes = 32, int iterations = 10000)
{
byte[] key = NetFxCrypto.DeriveBytes.GetBytes(password, salt, iterations, keyLengthInBytes);
return key;
}

public static byte[] EncryptAes(string data, string password, byte[] salt)
{
byte[] key = CreateDerivedKey(password, salt);
ISymmetricKeyAlgorithmProvider aes = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesEcbPkcs7);
ICryptographicKey symetricKey = aes.CreateSymmetricKey(key);
var bytes = WinRTCrypto.CryptographicEngine.Encrypt(symetricKey, Encoding.UTF8.GetBytes(data));
return bytes;
}
public static string DecryptAes(byte[] data, string password, byte[] salt)
{
byte[] key = CreateDerivedKey(password, salt);
ISymmetricKeyAlgorithmProvider aes = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesEcbPkcs7);
ICryptographicKey symetricKey = aes.CreateSymmetricKey(key);
var bytes = WinRTCrypto.CryptographicEngine.Decrypt(symetricKey, data);
return Encoding.UTF8.GetString(bytes, 0, bytes.Length);
}
}
Шифрую на клиенте логин и пароль пользователя перед отправкой:var salt = Crypto.CreateSalt(16);
var bytes = Crypto.EncryptAes(data, pass, salt);
Расшифровываю на сервере:var str = Crypto.DecryptAes(bytes, pass, salt);
Когда тестил в одном приложении то все работало. Как только разнес части на сервер и клиент, то возникли трудности при конвертировании byte[] в string и обратно. использовал Convert.ToString() и Encoding.UTF8.GetBytes/GetString. При использовании этих функций получается разные значения в массиве байт.
Нашел такой пример:stackoverflow.com/questions/472906/converting-a-st...
Использовал первый ответ:static byte[] GetBytes(string str)
{
var bytes = new byte[str.Length * sizeof(char)];
Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
static string GetString(byte[] bytes)
{
var chars = new char[bytes.Length / sizeof(char)];
Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
return new string(chars);
}
На одной машине работает. Но в комментариях к данном ответу что-то сказано что данный способ будет работать только на одной машине. Возможности проверить на разных машинах нет.
Про SSL знаю, но использовать его пока не буду.
Соль передаю вместе с зашифрованным текстом так она генерируется каждый раз при шифровании. Вроде это (новая генерация соли) увеличивает шансы от взломала методом перебора по радужным таблицам или как то так.
Скажите пожалуйста, в рамках одной версии net.framework но на разных устройствах этот код будет работать? Правильно ли будут происходить преобразования со строками? И может есть более универсальные решения?

21 Авг 2019 в 07:13
322 +1
0
Ответы
1

Да, преобразование byte[] в string и обратно может вызвать проблемы при передаче данных между разными устройствами из-за различий в кодировках и представлении символов.

Для универсального и безопасного способа передачи данных между клиентом и сервером рекомендуется использовать сериализацию данных в формат JSON. Например, вы можете использовать библиотеку Newtonsoft.Json для сериализации объектов в JSON и обратно.

Пример использования Newtonsoft.Json для сериализации и десериализации данных:

using Newtonsoft.Json;
public static class Crypto
{
public static byte[] EncryptAes(string data, string password, byte[] salt)
{
byte[] key = CreateDerivedKey(password, salt);
ISymmetricKeyAlgorithmProvider aes = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesEcbPkcs7);
ICryptographicKey symetricKey = aes.CreateSymmetricKey(key);
var bytes = WinRTCrypto.CryptographicEngine.Encrypt(symetricKey, Encoding.UTF8.GetBytes(data));
return bytes;
}
public static string DecryptAes(byte[] data, string password, byte[] salt)
{
byte[] key = CreateDerivedKey(password, salt);
ISymmetricKeyAlgorithmProvider aes = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesEcbPkcs7);
ICryptographicKey symetricKey = aes.CreateSymmetricKey(key);
var bytes = WinRTCrypto.CryptographicEngine.Decrypt(symetricKey, data);
return Encoding.UTF8.GetString(bytes, 0, bytes.Length);
}
}
// Serialize data to JSON before sending to server
var saltJson = JsonConvert.SerializeObject(salt);
var dataJson = JsonConvert.SerializeObject(bytes);
// Deserialize data from JSON on server side
var salt = JsonConvert.DeserializeObject<byte[]>(saltJson);
var bytes = JsonConvert.DeserializeObject<byte[]>(dataJson);

Таким образом, используя сериализацию в JSON, вы можете безопасно передавать данные между клиентом и сервером, обходя проблемы с различными форматами кодировки и представления данных.

20 Апр в 13:05
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Название заказа не должно быть пустым
Введите email
Бесплатные доработки
Гарантированные бесплатные доработки
Быстрое выполнение
Быстрое выполнение от 2 часов
Проверка работы
Проверка работы на плагиат
Интересные статьи из справочника
Поможем написать учебную работу
Название заказа не должно быть пустым
Введите email
Доверьте свою работу экспертам
Разместите заказ
Наша система отправит ваш заказ на оценку 92 648 авторам
Первые отклики появятся уже в течение 10 минут
Прямой эфир