AOP through Unity interceptors - Cryptography

Today, in our AOP serie, we will use Unity to encrypt/decrypt our data.

Let's imagine that you have a repo that stores personal information about users.
You may want some of this data to be encrypted, in case your database is stolen, or accessed illegaly.

Once again, AOP helps us in this situation. Let's build our sample. We will need an interface & an implementation representing the user repository.
public interface IUserRepo
    {
        bool IsUserAuthenticated(string login, [Encrypt] string password);         
        [Decrypt]
        string GetPasswordForUser(string login);
    }

public class UserRepoImpl : IUserRepo
    {
        public bool IsUserAuthenticated(string login, string password)
        {
            if (password == "1234")
                return false;

            return true;
        }

        public string GetPasswordForUser(string login)
        {
            return "wOSHX/n2NyWWn53YXVvJIg==";
        }
    }

Using this fake implementation, we just want to check that the password we use is really encrypted.
The  Decrypt & Encrypt attributes are really simple:
public class DecryptAttribute : Attribute
    { }


public class EncryptAttribute : Attribute
    { }


Finally, here is the service usage:

static void Main(string[] args)
        {
            using (var container = new UnityContainer())
            {
                container.AddNewExtension<Interception>();

                // Register
                container.RegisterType<IUserRepo, UserRepoImpl>(
                    new Interceptor<InterfaceInterceptor>(),
                    new InterceptionBehavior<CryptographicInterceptionBehavior>());

                // Resolve
                IUserRepo userRepo = container.Resolve<IUserRepo>();
             
                // Call
                bool isUserAuthenticated = userRepo.IsUserAuthenticated("John Doe", "1234");
                if (isUserAuthenticated == false)
                    throw new Exception("Encryption did not work");                 string password = userRepo.GetPasswordForUser("John Doe");

                if (password != "1234")
                    throw new Exception("Encryption did not work");

                Console.WriteLine("END");
                Console.ReadLine();
            }
        }


Let's now see how the CryptographicInterceptionBehavior is defined
public class CryptographicInterceptionBehavior : IInterceptionBehavior
    {
        public IEnumerable<Type> GetRequiredInterfaces()
        {
            return Type.EmptyTypes;
        }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {
            var parameters = input.MethodBase.GetParameters();

            foreach (var parameter in parameters)
            {
                if (parameter.GetCustomAttribute<EncryptAttribute>() != null)
                {
                    input.Arguments[parameter.Position] = Encrypt(input.Arguments[parameter.Position]);
                }
            }            var result = getNext()(input, getNext);

            if (input.MethodBase.GetCustomAttribute<DecryptAttribute>() != null)
            {
                return input.CreateMethodReturn(Decrypt(result.ReturnValue));
            }

            return result;
        }

        private object Encrypt(object input)
        {
            return StringCipher.Encrypt(input.ToString(), "");
        }

        private object Decrypt(object input)
        {
            return StringCipher.Decrypt(input.ToString(), "");
        }

        public bool WillExecute
        {
            get { return true; }
        }
    }

The StringCipher class used in this class is the one described by CraigTP in this blog post: http://stackoverflow.com/questions/10168240/encrypting-decrypting-a-string-in-c-sharp.

One advantage of using AOP to encrypt/decrypt data is that all the stuff are centralized into one place.

Comments

Popular posts from this blog

EMGU with Xamarin Forms guide [part 1]

[Xamarin Forms] Custom bottom bordered entry (iOS & Android)

Set your browser on Fire with P5.js