How To Implement SQLite Column Encryption in Windows Phone & WINRT


Security is critical element in Mobile application development. How application secure the user data is very important. Today Mobile hackers can easy access your application storage files using different tools.We can’t prevent mobile hacking but we can provide data security in various levels. Here I would like to show simple solution for offline support apps by using SQLite database. As you know Windows Phone/Windows 8 SQlite API is not supporting column encryption, But We can easily implement this in simple way.
1) Use of C# Attributes
2) EncyptiontUtil for Data encryption and decryption
3) Mark Column as EncyrptAttribute
4) Assign encrypted value to column data before insert or update

Step 1)
Create EncyrptAttribute class inside the SQLite.cs file

[AttributeUsage(AttributeTargets.Property)]
public class EncyrptAttribute : Attribute
{
}

Step 2)
Create EncyptiontUtil class for encyption decryption place inside the SQLite.cs file

public class EncyptiontUtil
{
public static string Encrypt(string value)
{
if (!string.IsNullOrEmpty(value))
{
var encybyes = ProtectedData.Protect(System.Text.Encoding.UTF8.GetBytes(value), null);
return Convert.ToBase64String(encybyes);// System.Text.Encoding.UTF8.GetString(encybyes, 0, encybyes.Length);
}
return value;
}

public static string Encrypt(object val)
{
string value = Convert.ToString(val);
return Encrypt(value);
}

public static string Decrypt(string value)
{
if (!string.IsNullOrEmpty(value))
{
var encybyes = ProtectedData.Unprotect(Convert.FromBase64String(value), null);
return System.Text.Encoding.UTF8.GetString(encybyes, 0, encybyes.Length);
}
return value;
}

public static string Decrypt(object val)
{
string value = Convert.ToString(val);
return Decrypt(value);
}
}

Step 3)

public class UserProfile
{
[SQLite.PrimaryKey]
public int UID { get; set; }

[SQLite.Encyrpt]
public string UserName { get; set; }

[SQLite.Encyrpt]
public string Password { get; set; }

}

Step 4)
Use the Encyption Util to assign value to column value in Insert Function

public int Insert(object obj, string extra, Type objType) {
....
.....
.....
var replacing = string.Compare(extra, "OR REPLACE", StringComparison.OrdinalIgnoreCase) == 0;

var cols = replacing ? map.InsertOrReplaceColumns : map.InsertColumns;
var vals = new object[cols.Length];
for (var i = 0; i < vals.Length; i++)
{
vals[i] = (cols[i].IsEncrypt) ? EncyptiontUtil.Encrypt(cols[i].GetValue(obj)) : cols[i].GetValue(obj);
}
.....
......
.....
}

//For Update
public int Update(object obj, Type objType)
{
......
.......
var cols = from p in map.Columns
where p != pk
select p;
var vals = from c in cols
select (c.IsEncrypt) ? EncyptiontUtil.Encrypt(c.GetValue(obj)) : c.GetValue(obj); //(c.IsEncrypt) ?
var ps = new List<object>(vals);
ps.Add(pk.GetValue(obj));
var q = string.Format("update \"{0}\" set {1} where {2} = ? ", map.TableName, string.Join(",", (from c in cols
select "\"" + c.Name + "\" = ? ").ToArray()), pk.Name);

try
{
rowsAffected = Execute(q, ps.ToArray());
}
.....
.....
}

Do not mark the primary key as encrypt attribute, For Delete and Update operation actual value is required to identify the row. You can download demo code below.

Happy Coding..!

SQLDB

SQLite DB encrypted values

Drawing Cropping Tool in WP7


Hi all my friends,

I would like to share my little knowledge with all yours. Here I explain how to draw cropping tool in wp7 for selecting cropping region in a image . Before I pleased to recommend that you must know the Path syntax. For more details please visit MSDN.

Followings required

  • Path Syntax
  • Dynamic Xaml Loader

Code:

 /// <summary>
        /// Draw path
        /// </summary>
        private void DrawOuterPath()
        {
            //Draw BackGround Image First
            //<Image Source="/WindowsPhoneApplication6;component/Images/hk_20080207_dictionary.jpg"></Image>
            string imageXaml = "<Image xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" Stretch=\"None\" Source=\"{Binding ImageSource}\"></Image>";
            Image imag = (Image)XamlReader.Load(imageXaml);
            ContentPanel.Children.Add(imag);

            ClearPath();

            //Check outter cordniates should contain X,Y points
            if (pathXYCordinates == null || pathXYCordinates.Length == 0)
            {
                throw new Exception("Outer Cordinates Empty");
            }

            //Get Main Grid X Y Cordinates
            //GeneralTransform gt = LayoutRoot.TransformToVisual(LayoutRoot);
            //Point p = gt.Transform(new System.Windows.Point(0, 0));
            double width = ContentPanel.ActualWidth;
            double height = ContentPanel.ActualHeight;
            string mainouterpathdata = null;

            // mainouterpathdata = string.Format("M{0},{1} L{2},{3} L{4},{5} L{6},{7} z", p.X, p.Y, p.X + width, p.Y, p.X + width, p.Y + height, p.X, p.Y + height);

            //Buld Path Data //M68,8 L228,32 L188,64 L148,48 z
            StringBuilder dataPath = new StringBuilder();
            dataPath.Append(string.Format("M{0},{1} L{2},{3} L{4},{5} L{6},{7} z", pathXYCordinates[0, 0], pathXYCordinates[0, 1], pathXYCordinates[1, 0], pathXYCordinates[1, 1], pathXYCordinates[2, 0], pathXYCordinates[2, 1],
                pathXYCordinates[3, 0], pathXYCordinates[3, 1]));

            //Create Outter Path
            string pathOutterXaml = "<Path xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" Name=\"pthOutter\" Data=\"" + mainouterpathdata + " " + dataPath.ToString() + "\" Stroke=\"Orange\" Fill=\"#AA000000\"></Path>";
            Path pathOutter = (Path)XamlReader.Load(pathOutterXaml);
            //For Crop Image 
            MainOuter = pathOutter;
            pathArray[0] = pathOutter;

            //Add to Page
            ContentPanel.Children.Add(pathOutter);

            //Draw SubPath 

            //************Draw Horizontal Path *******************//
            //Get X & Y cordinates for Left Vertical Path |
            double[,] leftPathXYPoints = GetXYPointCollections(Postion.Left);

            //Get X & Y cordinates for Right Vertical Path |
            double[,] rightPathXYPoints = GetXYPointCollections(Postion.Right);

            //Draw Path
            for (int indx = 0; indx < 3; indx++)
            {
                //Build Paths
                string pathdatatemp = string.Format("M{0},{1} L{2},{3}", leftPathXYPoints[indx, 0], leftPathXYPoints[indx, 1], rightPathXYPoints[indx, 0], rightPathXYPoints[indx, 1]);

                //Create Path
                string pathXaml = "<Path xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" Name=\"pathh" + indx.ToString() + "\" StrokeThickness=\"2\" StrokeDashArray=\"4\" Data=\"" + pathdatatemp + "\" Stroke=\"Orange\"/>";
                Path pathHorizontal = (Path)XamlReader.Load(pathXaml);
                pathArray[indx + 1] = pathHorizontal;
                //Add to Page
                ContentPanel.Children.Add(pathHorizontal);
            }

            //************Draw Verical Path *******************//
            //Get X & Y cordinates for Left Vertical Path |
            double[,] topPathXYPoints = GetXYPointCollections(Postion.Top);

            //Get X & Y cordinates for Right Vertical Path |
            double[,] bottomPathXYPoints = GetXYPointCollections(Postion.Bottom);

            //Draw Path
            for (int indx = 0; indx < 3; indx++)
            {
                //Build Paths
                string pathdatatemp = string.Format("M{0},{1} L{2},{3}", topPathXYPoints[indx, 0], topPathXYPoints[indx, 1], bottomPathXYPoints[indx, 0], bottomPathXYPoints[indx, 1]);

                //Create Path
                string pathXaml = "<Path xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" Name=\"pathv" + indx.ToString() + "\" StrokeThickness=\"2\" StrokeDashArray=\"4\" Data=\"" + pathdatatemp + "\" Stroke=\"Orange\"/>";
                Path pathVertical = (Path)XamlReader.Load(pathXaml);
                pathArray[indx + 4] = pathVertical;

                //Add to Page
                ContentPanel.Children.Add(pathVertical);
            }
 /// <summary>
        /// Get X & Y Cordinates Collection to draw the Sub Path
        /// </summary>
        /// <param name="postn"></param>
        /// <returns></returns>
        private double[,] GetXYPointCollections(Postion postn)
        {
            //double lastcordinateX = 0;
            //double lastCordinateY = 0;
            double heightY = 0;
            double widthX = 0;
            double xTemp = 0;
            double yTemp = 0;
            switch (postn)
            {
                case Postion.Left:
                    //lastcordinateX = pathXYCordinates[3, 0];
                    //lastCordinateY = pathXYCordinates[3, 1];

                    //Calculate Height
                    heightY = (pathXYCordinates[3, 1] - pathXYCordinates[0, 1]);
                    //Calculate Width 
                    widthX = (pathXYCordinates[3, 0] - pathXYCordinates[0, 0]);

                    //Start Points
                    xTemp = pathXYCordinates[0, 0];
                    yTemp = pathXYCordinates[0, 1];
                    break;

                case Postion.Right:
                    //Calculate Height
                    heightY = (pathXYCordinates[2, 1] - pathXYCordinates[1, 1]);
                    //Calculate Width 
                    widthX = (pathXYCordinates[2, 0] - pathXYCordinates[1, 0]);

                    //Start Points
                    xTemp = pathXYCordinates[1, 0];
                    yTemp = pathXYCordinates[1, 1];
                    break;

                case Postion.Top:
                    //Calculate Height
                    heightY = (pathXYCordinates[1, 1] - pathXYCordinates[0, 1]);
                    //Calculate Width 
                    widthX = (pathXYCordinates[1, 0] - pathXYCordinates[0, 0]);

                    //Start Points
                    xTemp = pathXYCordinates[0, 0];
                    yTemp = pathXYCordinates[0, 1];
                    break;

                case Postion.Bottom:
                    //Calculate Height
                    heightY = (pathXYCordinates[2, 1] - pathXYCordinates[3, 1]);
                    //Calculate Width 
                    widthX = (pathXYCordinates[2, 0] - pathXYCordinates[3, 0]);

                    //Start Points
                    xTemp = pathXYCordinates[3, 0];
                    yTemp = pathXYCordinates[3, 1];
                    break;
            }

            //Divide Height & Width by 4 (4 divisions) // NEED to check zero conditions
            double portionY = heightY / 4;
            double portionX = widthX / 4;

            //Store X & Cordinates
            double[,] newCordinates = new double[3, 2];

            for (int indx = 0; indx < 3; indx++)
            {
                newCordinates[indx, 0] = xTemp = portionX + xTemp; //Get X
                newCordinates[indx, 1] = yTemp = portionY + yTemp; //Get Y

            }
            return newCordinates;

        }

Call Server Side Method without postback


Call Server Side Method without postback

Here i am to going explain little bit about how to call a Severside method without postbacking page, It is very simple learn and use. First we need to implement the ICallbackEventHandler interface to your code and also the two methods in that RaiseCallbackEvent and GetCallbackResult . Here is the sample code for that.

Partial Public Class WebForm3ClientCall

Inherits System.Web.UI.Page

Implements System.Web.UI.ICallbackEventHandler

Protected returnValue As String

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

Dim cbReference As String = Page.ClientScript.GetCallbackEventReference(Me, "arg", "ReceiveServerData", "context")

Dim callbackScript As String = ""

callbackScript = "function CallServer(arg, context)" + "{ " + cbReference + ";}"

Page.ClientScript.RegisterClientScriptBlock(Me.GetType(), "CallServer", callbackScript, True)

End Sub

Public Sub RaiseCallbackEvent(ByVal eventArgument As String) Implements ICallbackEventHandler.RaiseCallbackEvent

If Not IsNumeric(eventArgument) Then

‘Call Buisness layer to get the Details here is sample demo code only you need your own logic to get some datas

Dim ObjPer As New Personal

returnValue=ObjPer.GetMydetailByID(eventArgument)

End If

End Sub

Public Function GetCallbackResult() As String Implements ICallbackEventHandler.GetCallbackResult

Return returnValue;

End Function

End End Class

And in Aspx code :

<asp:TextBox ID=”txtwebin” runat=”server” Width=”200px”

MaxLength=”100></asp:TextBox>

<img src=”Get.gif” height=”24px” width=”25px” alt=”Get Address” onclick=”GetMyAddress()” />

<script type=”text/javascript”>

function ReceiveServerData(rValue)
{
Alert(“Your Address is “+rValue);
}

function GetMyAddress ()
{
Var myname= document.getElementById (‘<%= txtwebin.ClientID %>’).value;
CallServer(myname, “”);
}        
<script/>

Now, type the your name and click the image you will get javascript alert box  says Your Address is ‘some data’

Generalized Class for Tombstone


Introduction

This is the simplest way for tombstoning using Reflection and custom attributes. We can use this code for tombstoning your application. I hope there is no need to explain the basic idea of Reflection and Attributes but if so then please refer to (Reflection).

Using the code

The basic idea behind my code is to catch the ViewModel Classes Properties which is marked as “IsTombStone” attributes. So by using reflection we can take those properties which are marked as Tombstone Attributes. Here is the Custom Attribute Class “IsTombStoneAttribute” & AppHibernate Class for Tombstone.

In AppHibernate class there are two public static method HiberNateViewModels() & RestoreViewModel(). This HiberNateViewmodel will get all the ViewModel static instances and then get all the properties which are marked as IsTomstone attributes and save the property name and it value to Collection List for Serialization.

RestoreViewModel will desterilize the collection list and assign to each value to each ViewModel properties.

So we can call the HiberNateViewModel method inside the App.xaml.cs

 

private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
AppHibernate.HiberNateViewModels();
}
//To restore the tombstoned data call RestoreViewModel inside App.Xaml.cs
private void Application_Activated(object sender, ActivatedEventArgs e)
{
AppHibernate.RestoreViewModel();
}

 To Mark a property as IsTombStone Use attributes

For example SearchText Property in X ViewModel. We can mark this property as 

[IsTombStone]
Public String SearchText
{
get { return searchText; }
Set { searchText=value;}
}
//
// Custom Attributes class
//
[AttributeUsage(AttributeTargets.Property)]
public class IsTombStoneAttribute : Attribute
{
public override string ToString()
{
return "IsTombStone";
}
}
public class KeyValue
{

#region "Properties"

private string viewModel;

private string key;

private Object valueData;

public string ViewModel
{

get
{
return viewModel;
}
set
{
viewModel = value;
}

}

public string Key
{
get
{
return key;
}

set
{
key = value;
}

}

public Object ValueData
{
get
{
return valueData;
}
set
{
valueData = value;
}
}

#endregion

#region "Constructor"

public KeyValue()
{

}

public KeyValue(string keypara, object valuepara, string viewmodelpara)
{

key = keypara;

valueData = valuepara;

viewModel = viewmodelpara;

}

#endregion

}

///

&lt;summary&gt;

/// This General class can be used anywhere; Better to NavigateTo &amp;amp; NavigateFrom overide methods in codebehind

/// Functionality : It store the property value to xml for tombstoning; The property should marks the attributes as [IsTombStone]

/// &lt;/summary&gt;



public class AppHibernate
{

#region Local Variables

private static Type[] typearray;

private static List&lt;KeyValue&gt; keyValuesList = new List&lt;KeyValue&gt;();

private const string FILENAME = "HibernateData.xml";

static List&lt;Type&gt; typList = new List&lt;Type&gt;();

#endregion

#region Methods

///

&lt;summary&gt;

/// Save the Property Value and its type

/// &lt;/summary&gt;



/// &lt;param name="typepara"&gt;&lt;/param&gt;

/// &lt;param name="instancepara"&gt;&lt;/param&gt;

private static void HiberNate(Type typepara, object instancepara)
{

try
{

PropertyInfo[] propCollections = typepara.GetProperties(BindingFlags.Public | BindingFlags.Instance);

for (int i = 0; i &lt; propCollections.Length; i++)
{

PropertyInfo myPropInfo = (PropertyInfo)propCollections[i];

object[] attributes = myPropInfo.GetCustomAttributes(true);

foreach (object attribIndx in attributes)
{

if (attribIndx.ToString() == "IsTombStone")
{

object value = myPropInfo.GetValue(instancepara, null);

if (value != null)
{

keyValuesList.Add(new KeyValue(myPropInfo.Name, value, typepara.FullName));

typList.Add(value.GetType());

}
}

}

}

}

catch (Exception)
{

}

}

///

&lt;summary&gt;

/// Restorte the saved state

/// &lt;/summary&gt;



/// &lt;param name="typepara"&gt;&lt;/param&gt;

/// &lt;param name="instancepara"&gt;&lt;/param&gt;

private static void RestoreState(Type typepara, object instancepara)
{

PropertyInfo[] propCollections = typepara.GetProperties(BindingFlags.Public | BindingFlags.Instance);

try
{

for (int i = 0; i &lt; propCollections.Length; i++) { PropertyInfo myPropInfo = (PropertyInfo)propCollections[i]; object[] attributes = myPropInfo.GetCustomAttributes(true); foreach (object attribIndx in attributes) { if (attribIndx.ToString() == "IsTombStone") { var count = keyValuesList.Count(x =&gt; x.Key == myPropInfo.Name);

if (count != 0)
{

var keysvalueobj = keyValuesList.First(x =&gt; x.Key == myPropInfo.Name);

object value = keysvalueobj.ValueData;

myPropInfo.SetValue(instancepara, value, null);

}
}
}
}
}

catch (Exception)
{

}

}

///

&lt;summary&gt;

/// Write the Property values to XML file

/// &lt;/summary&gt;



private static void BackUp()
{

try
{

XmlSerializer SerializerObj = new XmlSerializer(typeof(List&lt;KeyValue&gt;), typearray);

IsolatedStorageFile iSF = IsolatedStorageFile.GetUserStoreForApplication();

if (iSF.FileExists(FILENAME))
{

iSF.DeleteFile(FILENAME);

}

IsolatedStorageFileStream fstream = new IsolatedStorageFileStream(FILENAME, FileMode.CreateNew, FileAccess.Write, iSF);

StreamWriter WriteFileStream = new StreamWriter(fstream);

SerializerObj.Serialize(WriteFileStream, keyValuesList);

WriteFileStream.Close();

}

catch (Exception)
{

//ErrorHandle.TraceErrorHandle("Unbale to Hibernate Data!!!");

}

}

///

&lt;summary&gt;

/// Restore Data and Assign to property

/// &lt;/summary&gt;



private static void RestoreData()
{

keyValuesList = null;

keyValuesList = new List&lt;KeyValue&gt;();

if (PhoneApplicationService.Current.State.ContainsKey("types"))
{

List&lt;string&gt; liststringtypes = (List&lt;string&gt;)PhoneApplicationService.Current.State["types"];

typearray = new Type[liststringtypes.Count];

for (int Indx = 0; liststringtypes.Count &gt; Indx; Indx++)
{

typearray[Indx] = Type.GetType(liststringtypes[Indx]);

}

PhoneApplicationService.Current.State.Remove("types");

}

XmlSerializer SerializerObj = new XmlSerializer(typeof(List&lt;KeyValue&gt;), typearray);

IsolatedStorageFile iSF = IsolatedStorageFile.GetUserStoreForApplication();

if (iSF.FileExists(FILENAME))
{

Stream ReadFileStream = new IsolatedStorageFileStream(FILENAME, FileMode.Open, FileAccess.Read, iSF);

try
{

keyValuesList = (List&lt;KeyValue&gt;)SerializerObj.Deserialize(ReadFileStream);

ReadFileStream.Close();

}

catch (Exception)

{ }

}

}

public static void HiberNateViewModels()
{

keyValuesList.Clear();

typList.Clear();

try
{

PropertyInfo[] propCollections = typeof(ViewModelLocator).GetProperties(BindingFlags.Static | BindingFlags.Public);

for (int i = 0; i &lt; propCollections.Length; i++) { PropertyInfo myPropInfo = (PropertyInfo)propCollections[i]; object value = myPropInfo.GetValue(null, null); HiberNate(myPropInfo.PropertyType, value); } if (keyValuesList.Count &gt; 0)
{

typearray = typList.ToArray();

BackUp();

List&lt;string&gt; liststringtypes = new List&lt;string&gt;();

foreach (Type typ in typList)
{

liststringtypes.Add(typ.AssemblyQualifiedName);

}

PhoneApplicationService.Current.State.Add("types", liststringtypes);

}

}

catch (Exception)

{ }

}

public static void RestoreViewModel()
{

RestoreData();

try
{

PropertyInfo[] propCollections = typeof(ViewModelLocator).GetProperties(BindingFlags.Static | BindingFlags.Public);

for (int i = 0; i &lt; propCollections.Length; i++)
{

PropertyInfo myPropInfo = (PropertyInfo)propCollections[i];

object value = myPropInfo.GetValue(null, null);

RestoreState(myPropInfo.PropertyType, value);

}

}

catch (Exception)
{

}
}
#endregion
}


Points of Interest

Just Call the HiberNateViewModel & RestoreViewModel inside App class for storing the properties value to XML file. No need to Page level data store.

GridView RowClick makes Row selectable


GridView RowClick makes Row selectable..

Here i discuss the GridView RowClick makes Row selectable without showing select(just named as “Select”) button leftside of gridview.
Basically we need CSS to hide the Select column.Here is the CSS class
Css Class :
.HideColumn
{
display:none;
width:0%;

}
Next part is change the Cursor and Add onClick Javascript event. For this use Gridview_RowCreated event in code behind file.

Private Sub Grdview_RowCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles Grdview.RowCreated
    Try
        'Checking Rowtype is DataRow
        If (e.Row.RowType = DataControlRowType.DataRow) Then
            'Change the Cursor style to Hand for this use CSS commands - cursor:hand;
            e.Row.Attributes.Add("style", "cursor:hand;")
            'Next find the Select button in Gridview
            'LnkDetails - Is the name i given for select button in gridview
            Dim LinkBtn As LinkButton = CType(e.Row.FindControl("LnkDetails"), LinkButton)
            If Not IsNothing(LinkBtn) Then
                'Add the onClick javascript event to raise the Grdview_SelectedIndexChanging Event
                'Here is the tricky part "javascript:__doPostBack" to raise the server side events ; Parameter should be clientId of the Select Button
                'Here is client side code of Select button :<a id="ctl00_ContentPlaceHolderTag_Grdview_ctl11_LnkDetails" href="javascript:__doPostBack('ctl00$ContentPlaceHolderTag$Grdview$ctl11$LnkDetails','')" style="display:inline-block;width:0%;">Details</a>
                'Client ID=ctl00_ContentPlaceHolderTag_Grdview_ctl11_LnkDetails replace _ with $ gives ctl00$ContentPlaceHolderTag$Grdview$ctl11$LnkDetails pass this as paramter of javascript:__doPostBack
                e.Row.Attributes.Add("onclick", "javascript:__doPostBack('" & LinkBtn.ClientID.Replace("_", "$") & "','')")
                'So now it is more flexiable to select Row without showing Select button and user can click anywhere in row makes fire Grdview_SelectedIndexChanging server event
            End If
        End If
    Catch ex As Exception
        'Log errors
    End Try
End Sub