As a server, I use ASP.NET WebApi 2. As a client, a universal application on Windows 10. Everywhere NET.Framework is used. 4.6 Data is sent via http.
For encryption using PCLCrypto https://github.com/aarnott/pclcrypto
Below is a class for encryption:
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); } } I encrypt the username and password on the client before sending:
var salt = Crypto.CreateSalt(16); var bytes = Crypto.EncryptAes(data, pass, salt); I decipher on the server:
var str = Crypto.DecryptAes(bytes, pass, salt); When testing in one application, everything worked. As soon as the parts were spread to the server and the client, difficulties arose in converting byte[] to string and back. used Convert.ToString() and Encoding.UTF8.GetBytes / GetString . Using these functions results in different values ββin the byte array.
Found such an example: https://stackoverflow.com/questions/472906/converting-a-string-to-byte-array-without-using-an-encoding-byte-by-byte?lq=1
Used the first answer:
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); } By one machine works. But in the comments to this answer, something is said that this method will work only on one machine. There is no opportunity to check on different machines. I know about SSL, but I will not use it yet.
The salt is transmitted along with the cipher text so it is generated every time it is encrypted. Like this (new salt generation) increases the chances of being hacked by brute force on rainbow tables or something like that.
Tell me please, within the same version of net.framework, but on different devices will this code work? Will the transformations take place correctly with strings? And maybe there are more universal solutions?