Monday, December 29, 2008

How to encrypt/decrypt with passphrase

I was stuck with this when I started using IIS7's AppCmd utility. The utility allows to export and import appication pool configuration, while not having an option to encode/decode identity password. But it was required to store the configuration under the source control system. So I decided to write a simple command-line encoding/decoding utility for a particular section being fetched by regular expression.

I use a symmetric algorithm because key is defined with passphrase for both encoding and decoding operations. Creating key from passphrase is based on hashing. We are required to have keys with fixed length and character sets, thus hashing goes a long way here:
var bytes = Encoding.Unicode.GetBytes(passphrase);
var key = SHA256Managed.Create().ComputeHash(bytes);
var iv = MD5.Create().ComputeHash(bytes);
Key and vector may have different requirements regarding length of byte arrays. For the RijndaelManaged class they are 32 and 16 respectively. Thus I use SHA256 and MD5 algorithms to get keys with the appropriate length.
var alg = SymmetricAlgorithm.Create();
var ms = new MemoryStream();
var buffer = Encoding.Unicode.GetBytes(text);
 
using (var enc = new CryptoStream(
    ms, alg.CreateEncryptor(key, iv),
    CryptoStreamMode.Write
))
{
    enc.Write(buffer, 0, buffer.Length);
}
The code above feeds the entire text to the CryptoStream. For passwords encoding it shouldn't be a perfomance issue. Decoding has quite similar implementation. Rather than using alg.CreateEncryptor it should use alg.CreateDecryptor there.

Additionally I use a couple of extention methods to format byte array to hexadecimal string and vice versa. Here are the entire Encode/Decode methods implementation and the helper methods:

private static string Encode(string text, string passphrase)
{
    var bytes = Encoding.Unicode.GetBytes(passphrase);
    var key = SHA256Managed.Create().ComputeHash(bytes);
    var iv = MD5.Create().ComputeHash(bytes);
 
    var alg = SymmetricAlgorithm.Create();
    var ms = new MemoryStream();
    var buffer = Encoding.Unicode.GetBytes(text);
 
    using(var enc = new CryptoStream(
        ms, alg.CreateEncryptor(key, iv),
        CryptoStreamMode.Write
    )) enc.Write(buffer, 0, buffer.Length);
 
    return ms.ToArray().ToHexString();
}
 
private static string Decode(string text, string passphrase)
{           
    var bytes = Encoding.Unicode.GetBytes(passphrase);
    var key = SHA256Managed.Create().ComputeHash(bytes);
    var iv = MD5.Create().ComputeHash(bytes);
 
    var alg = SymmetricAlgorithm.Create();
    var ms = new MemoryStream();
 
    var buffer = text.ToByteArray();
 
    try
    {
        using (var enc = new CryptoStream(
            ms, alg.CreateDecryptor(key, iv),
            CryptoStreamMode.Write
        )) enc.Write(buffer, 0, buffer.Length);
    }
    catch (Exception)
    {
        Console.Error.WriteLine("Error: wrong passphrase.");
        Environment.Exit(2);
    }
 
    return Encoding.Unicode.GetString(ms.ToArray());
}
...
internal static string ToHexString(this byte[] bytes)
{
    StringBuilder builder = new StringBuilder(3 * bytes.Length);
 
    for (int i = 0; i < bytes.Length; i++)
    {
        builder.AppendFormat("{0:x2}", bytes[i]);
    }
 
    return builder.ToString().ToLowerInvariant();
}
 
internal static byte[] ToByteArray(this string hexString)
{
    byte[] buffer = new byte[hexString.Length / 2];
 
    for (int i = 0; i < hexString.Length; i += 2)
    {
        buffer[i / 2] = byte.Parse(hexString.Substring(i, 2), NumberStyles.HexNumber);
    }
   
    return buffer;
}

2 comments:


  1. Best Article buy Pain Pills online Excellent post. I appreciate this site. Stick with it! Because the admin of this web page is working, no doubt very quickly it will be well-known, due to its quality contents.This website was how do you say it? Relevant!! Finally, I’ve found something that helped me.
    Best Article buy Roxicodone online Excellent post
    buy Xanax online
    buy Oxycodone online

    Best Article buy Pain Medications online Excellent post. I appreciate this site. Stick with it! Because the admin of this web page is working, no doubt very quickly it will be well-known, due to its quality contents.This website was how do you say it? Relevant!! Finally, I’ve found something that helped me.

    buy Research Chemicals online

    buy Roxicodone online

    buy Cbd Isolate online

    ReplyDelete