В качестве сервера использую ASP.NET WebApi 2.
В качестве клиента универсальное приложение на Windows 10
Везде используется NET.Framework 4.6
Данные пересылаются по http.
Для шифрования использую PCLCrypto
https://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 но на разных устройствах этот код будет работать? Правильно ли будут происходить преобразования со строками? И может есть более универсальные решения?