using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;
namespace EncryptionTester
{
class RijndaelWrapper
{
// Retruns salt from password.
private static byte[] Password2Salt(String password)
{
int saltLength = password.Length * ((int)password[0] % 3 + 2);
saltLength = Math.Max(8, saltLength);
byte[] resSalt = new byte[saltLength];
for (int i = 0; i < saltLength; ++i)
resSalt[i] =
Convert.ToByte(password[i % password.Length] ^ (i + 17));
return resSalt;
}
// Returns symmetric algorithm with key, IV and salt extracted from
// password string.
private static SymmetricAlgorithm GetAlgorithm(string password)
{
// Init key
byte[] saltBytes = Password2Salt(password);
Rfc2898DeriveBytes rfc2898 =
new Rfc2898DeriveBytes(password, saltBytes);
// Init algorithm
SymmetricAlgorithm sa = new RijndaelManaged();
sa.Key = rfc2898.GetBytes(sa.KeySize / 8);
sa.IV = rfc2898.GetBytes(sa.BlockSize / 8);
return sa;
}
// Encrypts text using password, returns encrypted string
// in base64 representation.
public static String Encrypt(String text, String password)
{
SymmetricAlgorithm sa = GetAlgorithm(password);
// Encrypt text
ICryptoTransform ict = sa.CreateEncryptor();
using (MemoryStream mso = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(mso, ict,
CryptoStreamMode.Write))
{
byte[] textByteArray = Encoding.UTF8.GetBytes(text);
cs.Write(textByteArray, 0, textByteArray.Length);
}
// Convert encrypted text from bytes to base64 representation
byte[] encryptedTextBytesArray = mso.ToArray();
string base64EncryptedText =
Convert.ToBase64String(encryptedTextBytesArray);
return base64EncryptedText;
}
}
// Decrypts text in base64 representation (thats what Encrypt() returns)
// using password, returns decrypted string. Throws CryptographicException
// in case of bad password, input text or other errors.
public static String Decrypt(String base64EncryptedText, String password)
{
SymmetricAlgorithm sa = GetAlgorithm(password);
// Decrypt text
ICryptoTransform ict = sa.CreateDecryptor();
using (MemoryStream mso = new MemoryStream())
{
using (CryptoStream sc = new CryptoStream(mso, ict,
CryptoStreamMode.Write))
{
byte[] base64EncryptedTextByteArray =
Convert.FromBase64String(base64EncryptedText);
sc.Write(base64EncryptedTextByteArray, 0,
base64EncryptedTextByteArray.Length);
}
// Return decrypted string
return Encoding.UTF8.GetString(mso.ToArray());
}
}
}
class Program
{
static void Main(string[] args)
{
// Input from user
string text = "a text we want to keep secret";
string password = "ourpass";
// Text to be sent over network, put to database, etc...
string encryptedText = RijndaelWrapper.Encrypt(text, password);
// Now we want to get decrypt text back
string decryptedText = string.Empty;
try
{
decryptedText = RijndaelWrapper.Decrypt(encryptedText, password);
}
catch (CryptographicException)
{
// Wrong password??
decryptedText = "??";
}
// Output results
Console.WriteLine("Text to encrypt : " + text);
Console.WriteLine("Base64 encrypted text : " + encryptedText);
Console.WriteLine("Decrypted text : " + decryptedText);
}
}
}