views:

77

answers:

1

Situation: suppose I have a column on an entity which is encrypted in the database using IUserType:

public class EncryptedStringUserType : IUserType
{

    public object NullSafeGet(IDataReader rs, string[] names, object owner)
    {
        object r = rs[names[0]];
        if (r == DBNull.Value)
            return null;
        return CryptoProvider.Instance.Decrypt((string) r);
    }

    public void NullSafeSet(IDbCommand cmd, object value, int index)
    {
        object paramVal = DBNull.Value;
        if (value != null)
            paramVal = CryptoProvider.Instance.Encrypt((string) value);
        IDataParameter parameter = (IDataParameter)cmd.Parameters[index];
        parameter.Value = paramVal;
    }

   // Other IUserType members as usual..
}

As explained by Ayende himself in: http://ayende.com/Blog/archive/2008/07/31/Entities-dependencies-best-practices.aspx

Now when querying, using the NHibernate IQuery interface, I need to encrypt the parameter I am passing into the Query:

query.SetString("DbEncryptedParameter", 
    CryptoProvider.Instance.Encrypt(UnencryptedValueObject.ToString()));

Question: Is there a better way of performing this query, leveraging the knowledge NHibernate has of this Encrypted Type, so the encryption doesn't have to be performed while setting the parameter?

A: 

Am I missing something? Why do you need to encrypt the value when sending it in? The point of IUserType is that you encapsulate the difference between the native form (plaintext) and persisted form (encrypted). When you provide the plaintext version to the query, NHibernate should be invoking the IUserType.NullSafeSet to encrypt the value and set the query parameter to the encrypted value.

Rich
Have you tried this or know this? I would say it's quite logical too, but it didn't seem to be this way.
Rick
Just because you are using encryption/decryption, this is no different than any other property-to-field translation using IUserType based translation. The most simple example is the built in YesNoType, which saves booleans as strings (YES or NO). When you interact with queries or Linq, you interact based on the POCO definition, not the DB definition. That's the whole point of IUserType.
Rich