20071217

AES (Rijndael) Encryption in C# - The ezed Way.

Wanna encrypt stuff? Well Check this awesome utility that i made...


Test....

using AwesomeUtilities;

using NUnit.Framework;

namespace Test

{

[TestFixture]

public class CryptographyUtilityTest

{

[Test]

public void Should_do_some_awesome_encrytion_stuff()

{

string toEncrypt = "Encrypt Me Stud";

string encrypted = CryptographyUtility.Encrypt(toEncrypt);

Assert.AreEqual(toEncrypt, CryptographyUtility.Decrypt(encrypted));

}

}

}



The shit that does the stuff




using System;

using System.IO;

using System.Security.Cryptography;

using System.Text;

namespace AwesomeUtilities

{

public abstract class CryptographyUtility

{

private static readonly string PASSWORD;

static CryptographyUtility()

{

PASSWORD = "MyUberPassword"; //Usually taken from a *.config

}

public static string Encrypt(string value)

{

return Encrypt(value, PASSWORD);

}

public static string Decrypt(string encryptedValue)

{

return Decrypt(encryptedValue, PASSWORD);

}

public static string Encrypt(string value, string password)

{

ValidateTextData(value, password);

Rfc2898DeriveBytes keyGenerator = new Rfc2898DeriveBytes(password, 8);

byte[] rawData = Encoding.Unicode.GetBytes(value);

using (MemoryStream memoryStream = new MemoryStream())

using (CryptoStream cryptoStream = new CryptoStream(memoryStream, GetRijndaelWith(keyGenerator).CreateEncryptor(), CryptoStreamMode.Write))

{

memoryStream.Write(keyGenerator.Salt, 0, keyGenerator.Salt.Length);

cryptoStream.Write(rawData, 0, rawData.Length);

cryptoStream.Close();

return Convert.ToBase64String(memoryStream.ToArray());

}

}

public static string Decrypt(string encryptedValue, string password)

{

ValidateTextData(encryptedValue, password);

byte[] rawData = GetRawData(encryptedValue);

using (MemoryStream memoryStream = new MemoryStream())

using (CryptoStream cryptoStream = new CryptoStream(memoryStream, GetRijndaelWith(new Rfc2898DeriveBytes(password, GetSalt(rawData))).CreateDecryptor(), CryptoStreamMode.Write))

{

cryptoStream.Write(rawData, 8, rawData.Length - 8);

cryptoStream.Close();

return Encoding.Unicode.GetString(memoryStream.ToArray());

}

}

private static Rijndael GetRijndaelWith(DeriveBytes keyGenerator)

{

Rijndael aes = Rijndael.Create();

aes.IV = keyGenerator.GetBytes(aes.BlockSize/8);

aes.Key = keyGenerator.GetBytes(aes.KeySize/8);

return aes;

}

private static byte[] GetRawData(string value)

{

byte[] rawData = Convert.FromBase64String(value);

if (rawData.Length < 8)

throw new ArgumentException("Invalid input value");

return rawData;

}

private static byte[] GetSalt(byte[] rawData)

{

byte[] salt = new byte[8];

for (int i = 0; i < salt.Length; i++)

salt[i] = rawData[i];

return salt;

}

private static void ValidateTextData(string value, string password)

{

if (string.IsNullOrEmpty(value))

throw new ArgumentException("No value given");

if (string.IsNullOrEmpty(password))

throw new ArgumentException("No password given");

}

}

}

WCF and Building your own Awesome WCF Web Service Proxy

Hate using the svcutil.exe to generate your proxy for a WCF web service? Ever wondered if you can make it generic? You came to the right place!

I can't stand the MPP WCF Service Factory, I don't like svcutil, so I tried to make it pimp!

So for this example, we will be getting 3 pimp names from a wcf web service. If you are not familliar with WCF, here are some things that I did:


  1. Used BasicHttpBinding to be backwards compatible with classic ASP.net
  2. Implemented impersonation (refer to the web.config in the clientcredential type)
  3. Did not use a *.config file on the client end, and hand rolled an awesome factory class that does some WCF kungfu!
  4. Ofcourse, NUnit skillz
Let's start with the service

PimpNameService.svc

<%@ ServiceHost Language="C#" Debug="true" Service="AwwYeaFoo.PimpNameService" CodeBehind="PimpNameService.cs" %>


<%@ ServiceHost Language="C#" Debug="true" Service="AwwYeaFoo.PimpNameService" CodeBehind="PimpNameService.cs" %>


PimpNameService.cs

using System.Collections.Generic;

using System.ServiceModel;

using AwwYeaFoo.Interface;

namespace AwwYeaFoo

{

public class PimpNameService : IPimpNameService

{

[OperationBehavior(Impersonation = ImpersonationOption.Required)]

public IEnumerable<string> GetAllPimpNames()

{

IList<string> pimpNames = new List<string>();

pimpNames.Add("Python");

pimpNames.Add("Diamond Trim");

pimpNames.Add("Reverend J Fresh");

return pimpNames;

}

}

}



IPimpNameService.cs

using System.Collections.Generic;

using System.ServiceModel;

namespace AwwYeaFoo.Interface

{

[ServiceContract]

public interface IPimpNameService

{

[OperationContract]

IEnumerable<string> GetAllPimpNames();

}

}



web.config

<configuration>

<system.serviceModel>

<services>

<service behaviorConfiguration="returnFaults" name="AwwYeaFoo.PimpNameService">

<endpoint binding="basicHttpBinding" bindingConfiguration="PimpBinding"

name="PimpNameServiceEndPoing" contract="AwwYeaFoo.Interface.IPimpNameService" />

</service>

</services>

<behaviors>

<serviceBehaviors>

<behavior name="returnFaults">

<serviceMetadata httpGetEnabled="true" />

</behavior>

</serviceBehaviors>

</behaviors>

<bindings>

<basicHttpBinding>

<binding name="PimpBinding">

<security mode="TransportCredentialOnly">

<transport clientCredentialType="Windows" />

</security>

</binding>

</basicHttpBinding>

</bindings>

</system.serviceModel>

</configuration>



The Test

[Test]

public void Should_get_all_pimp_names_using_the_AwesomeWCFWebServiceProxy()

{

using (AwesomeWCFWebServiceProxy<IPimpNameService> proxy =

new AwesomeWCFWebServiceProxy<IPimpNameService>(@"http://localhost/AwwYeaFoo/pimpnameservice.svc"))

{

IEnumerable<string> pimpNames = proxy.GetProxy().GetAllPimpNames();

foreach (string pimpName in pimpNames)

{

Console.Out.WriteLine(pimpName);

}

}

}



AwesomeWCFWebServiceProxy.cs


public class AwesomeWCFWebServiceProxy<WCFWebServiceInterface> : IDisposable

{

private BasicHttpBinding binding;

private ChannelFactory<WCFWebServiceInterface> factory;

protected WCFWebServiceInterface proxy;

private readonly string url;

public AwesomeWCFWebServiceProxy(string url)

{

this.url = url;

InitializeHTTPBinding();

InitializeChannelFactory();

InitializeProxy();

}

private void InitializeHTTPBinding()

{

binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportCredentialOnly);

binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;

}

private void InitializeChannelFactory()

{

factory = new ChannelFactory<WCFWebServiceInterface>(

binding, new EndpointAddress(url));

factory.Credentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;

}

private void InitializeProxy()

{

proxy = factory.CreateChannel();

}

public WCFWebServiceInterface GetProxy()

{

return proxy;

}

public void Dispose()

{

((IChannel)proxy).Close();

factory.Close();

}

}