using System;
using System.IO;
using System.Security.Cryptography;
// https://stackoverflow.com/a/2791259
// AES-256-CBC
public class Crypto {
/*
notes:
- key size = 256 bits (32 bytes)
- block/iv size = 128 bits (16 bytes)
*/
private static void WriteBytes(byte[] bytes) {
for (int i = 0; i < bytes.Length; i++) {
byte b = bytes[i];
Console.Write("0x" + b.ToString("x2"));
bool last = i == bytes.Length - 1;
Console.Write(last ? Environment.NewLine : ", ");
}
}
// https://www.random.org/bytes/
private static byte[] _salt = { 0x28, 0x7c, 0x6a, 0xa2, 0x2e, 0xa6, 0x46, 0x4b, 0x68, 0xef, 0x91, 0xec, 0x0e, 0x8c, 0x3e, 0x50 };
public static string EncryptString(string plainText, string sharedSecret) {
string outStr = null;
RijndaelManaged algorithm = null;
try {
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(sharedSecret, _salt);
algorithm = new RijndaelManaged();
algorithm.Key = key.GetBytes(algorithm.KeySize / 8); // 32 bytes for a key
ICryptoTransform encryptor = algorithm.CreateEncryptor(algorithm.Key, algorithm.IV);
using (MemoryStream msEncrypt = new MemoryStream()) {
msEncrypt.Write(algorithm.IV, 0, algorithm.IV.Length);
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
swEncrypt.Write(plainText);
outStr = Convert.ToBase64String(msEncrypt.ToArray());
}
} finally {
if (algorithm != null)
algorithm.Clear();
}
return outStr;
}
public static string DecryptString(string cipherText, string sharedSecret) {
RijndaelManaged algorithm = null;
string plaintext = null;
try {
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(sharedSecret, _salt);
byte[] bytes = Convert.FromBase64String(cipherText);
using (MemoryStream msDecrypt = new MemoryStream(bytes)) {
algorithm = new RijndaelManaged();
algorithm.Key = key.GetBytes(algorithm.KeySize / 8);
algorithm.IV = DeriveIV(msDecrypt, algorithm.BlockSize / 8);
ICryptoTransform decryptor = algorithm.CreateDecryptor(algorithm.Key, algorithm.IV);
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
plaintext = srDecrypt.ReadToEnd();
}
} finally {
if (algorithm != null)
algorithm.Clear();
}
return plaintext;
}
private static byte[] DeriveIV(Stream s, int length) {
byte[] iv = new byte[length];
if (s.Read(iv, 0, length) != length)
throw new Exception("Failed to derive IV from stream.");
return iv;
}
}
Comments