Friday 6 May 2016

Symmetric crypto algorithms in C# with MonoDevelop and GTK-Sharp

Using MonoDevelop and GTK-Sharp (GTK#) offers a .NET developer to develop applications for other platforms such as applications in Linux and other OS-es. Let's look more at the very able MonoDeveloper IDE and GTK-Sharp. As a .NET developer who has written .NET applications for many years, MonoDevelop has fully matured into a very good platform to develop a multitiude of applications. GTK# resembles .NET Windows Forms in many ways. We will here use some symmetric crypto algorithms in .NET that is available with Mono framework. The demo provides Digital Encryption Standard (DES) and Triple-DES, plus the Advanced Encryption Standard (AES) - Rijndael. The GUI will look like this:

The GUI is designed with the GUI designer Stetic in Monodevelop, for developing GTK#-applications. We can choose the Mode of the cryptographic algorithm, default here is Cipher Block Chaining. We can also set the padding of the cryptographic algorithm. Note that not all combinations are legal. I have tested with Rijndael, Cipher Block Chaining and padding set to Zeros, which seems to be working ok. You can use the demo here to test out other combinations. You can also generate different Initialization Vectors and Keys to use with the algorithm.

The code to achieve the encryption and decryption is listed below:

using System;
using System.Security.Cryptography;
using Gtk;
using System.IO;

public partial class MainWindow: Gtk.Window
{

 private SymmetricAlgorithm _symmetricAlgorithm; 
 private byte[] _intializationVector; 
 private byte[] _key;
 private byte[] _cipherBytes;



 public MainWindow () : base (Gtk.WindowType.Toplevel)
 {
  Build ();
 }

 protected void OnDeleteEvent (object sender, DeleteEventArgs a)
 {
  Application.Quit ();
  a.RetVal = true;
 }

 protected void btnGenerateIVClick (object sender, EventArgs e)
 {
     _symmetricAlgorithm = CreateSymmetricAlgorithm (); 

  _symmetricAlgorithm.GenerateIV ();
  _intializationVector = _symmetricAlgorithm.IV;

  lbInitializationVector.Text = Convert.ToBase64String(_symmetricAlgorithm.IV);

//  MessageDialog msgBox = new MessageDialog (null, DialogFlags.Modal, 
//                      MessageType.Info, ButtonsType.Ok, "Why hello world!");
//  msgBox.Run ();
//  msgBox.Destroy ();
 }

 protected void btnEncrypt_Click (object sender, EventArgs e)
 {
  _symmetricAlgorithm = CreateSymmetricAlgorithm (); //ensure that we use the selected algorithm
  _cipherBytes = Encrypt(textviewPlainText.Buffer.Text);
  textviewCipher.Buffer.Text = Convert.ToBase64String(_cipherBytes); 
 }

 private byte[] Encrypt(string text){
  byte[] encrypted;
  ICryptoTransform encryptor = _symmetricAlgorithm.CreateEncryptor (_key, _intializationVector);
  using (MemoryStream msEncrypt = new MemoryStream ()) {
   using (CryptoStream csEncrypt = new CryptoStream (msEncrypt, encryptor, CryptoStreamMode.Write)) {
    using (StreamWriter swWriter = new StreamWriter (csEncrypt)) {
     swWriter.Write (text);
    }
    encrypted = msEncrypt.ToArray (); 
   }

  }
  return encrypted;
 }

 private string Decrypt(byte[] cipherBytes){
  try {
   ICryptoTransform decryptor = _symmetricAlgorithm.CreateDecryptor (_key, 
    _intializationVector);
   using (MemoryStream msEncrypt = new MemoryStream (cipherBytes)) {
    using (CryptoStream csEncrypt = new CryptoStream (msEncrypt, decryptor,
     CryptoStreamMode.Read)) {
     using (StreamReader sReader = new StreamReader (csEncrypt)) {
      string decrypted = sReader.ReadToEnd();
      return decrypted;
     }
    } 
   }
  } catch (Exception err) {
   Console.WriteLine (err.Message);
  }
  return string.Empty;
 }

 private SymmetricAlgorithm CreateSymmetricAlgorithm(){
  SymmetricAlgorithm sa = null;
  if (rbDES.Active)
   sa = DESCryptoServiceProvider.Create ();
  if (rbThreeDES.Active)
   sa = TripleDESCryptoServiceProvider.Create ();
  if (rbRijndael.Active)
   sa = RijndaelManaged.Create ();

  if (sa == null)
   sa = DESCryptoServiceProvider.Create (); 

  if (_intializationVector != null)
   sa.IV = _intializationVector;
  if (_key != null)
   sa.Key = _key;

  sa.Mode = GetCipherMode ();
  sa.Padding = GetPadding ();
  return sa;
 }

 private PaddingMode GetPadding(){
  if (rbPaddingNone.Active)
   return PaddingMode.None;
  if (rbPaddingZeros.Active)
   return PaddingMode.PKCS7;
  if (rbPaddingAnsiX923.Active)
   return PaddingMode.ANSIX923;
  if (rbPaddingISO1126.Active)
   return PaddingMode.ISO10126;
  return PaddingMode.Zeros;
 }

 private CipherMode GetCipherMode(){
  if (rbCBC.Active)
   return CipherMode.CBC;
  if (rbCFB.Active)
   return CipherMode.CFB;
  if (rbCTS.Active)
   return CipherMode.CTS;
  if (rbECB.Active)
   return CipherMode.ECB;
  if (rbOFB.Active)
   return CipherMode.OFB;

  return CipherMode.CBC;
 }

 protected void btnKeyClick (object sender, EventArgs e)
 {
  _symmetricAlgorithm = CreateSymmetricAlgorithm ();     

  _symmetricAlgorithm.GenerateKey ();  
  _key = _symmetricAlgorithm.Key;
  lblKey.Text = Convert.ToBase64String (_symmetricAlgorithm.Key);
 }

 protected void btnDecryptClick (object sender, EventArgs e)
 {
  _symmetricAlgorithm = CreateSymmetricAlgorithm (); //ensure that we use the selected algorithm
  string decrypted = Decrypt(Convert.FromBase64String(textviewCipher.Buffer.Text));
  textviewDecrypted.Buffer.Text = decrypted; 
 }
}











To open up this sample, I have uploaded the MonoDevelop project as a tar.bz2 file available for download here: Sample project Monodevelop in this article To unzip the tar bunzip2 file, just the following command:
tar xjvf Symmetric.tar.bz2 

Just so you know:
tar - Tape ARchiver
And the options:
x - extract
v - verbose output (lists all files as they are extracted)
j - deal with bzipped file
f - read from a file, rather than a tape device

"tar --help" will give you more options and info

After unpacking, just open the solution in MonoDevelop.





Wednesday 4 May 2016

Creating a simple MD5 application using GTK# and Monodevelop

Let's look at building a simple application using GTK# and Monodevelop! I created this application using a Ubuntu 16.04 Xenial AMD64 Distribution of Linux running inside an Oracle VM VirtualBox on my Windows 10 Machine! First off, this article will show a very simple application written in Monodevelop IDE using GTK# to build a GUI. It resembles somewhat Windows Forms if you come from a Visual Studio background, such as I do. The application just takes some text input (plaintext) and computes a MD5 hash. Simple stuff. Defining the following form in MainWindow of the GTK# application: Moving over to the code bit, I define the following in MainWindow (Source of the form), which is the code behind:

using System;
using System.Linq;
using Gtk;
using System.Security.Cryptography;
using System.Text;


public partial class MainWindow: Gtk.Window
{
 public MainWindow () : base (Gtk.WindowType.Toplevel)
 {
  Build ();
  btnMd5.Clicked += OnBtnClick;
 }

 protected void OnDeleteEvent (object sender, DeleteEventArgs a)
 {
  Application.Quit ();
  a.RetVal = true;
 }

 protected void OnBtnClick (object sender, EventArgs args)
 {
  var md5 = MD5CryptoServiceProvider.Create ();
  byte[] plainTextBytes = Encoding.UTF8.GetBytes (tbPlainText.Buffer.Text); 
  byte[] hashBytes = md5.ComputeHash (plainTextBytes); 
  var sbuilder = new StringBuilder (); 

  sbuilder.Append(string.Join("",
  hashBytes.Select(x => x.ToString("x2")))); 
  tbHash.Buffer.Text = sbuilder.ToString();
 }

}



The code above instantiates a MD5CryptoServiceProvder instance, then computes a hash. We get a string representation of the MD5 hash using a StringBuilder and we use ToString("x2") - which assembles a hexidecimal string for us, which is the common way to represent a MD5 hash. A MD5 hash produces 128 bits = 16 bytes = 32 hexidecimal digits. A hexadecimal value can be 0-9 and A-F = 16 different values = one half byte.

We build up our GUI using the GUI designer inside Monodevelop. The GUI designer for GTK# in Monodevelop is called Stetic.
Stetic

Friday 22 April 2016

Transfering a commit message from Git to Target Process

It is possible to transfer a commit message from Git to Target Process using the REST Api of TP. This is done using hooks in Git. The problem is that the hook is written using bash shell scripts (or perl) and unlike Mercurial - Git does not sport an obvious choice of tool to develop such hooks. I am going to present below a hook I wrote in bash shell to transmit your commit message to TP. I choose to do this in the post-commit hook. First off, go to the source repository you are working with and into the .git subfolder. Then go into the hooks folder. Now add a new file called: post-commit Ok, so now we add our hook:

#!/bin/sh
#
# Overfører kommentar fra Git til Target Process
# Bruk - Formater kommentaren som: 
# TP TASKID: Min innsjekkingskommentar her
#
# Dette vil overføre så kommentarer til TP 
# Merk: 
# Erstatt verdiene i scriptet som heter TP_LOGON og TP_PASSWORD
# med ditt pålogging til TP. Vil du ikke inkludere passordet ditt til TP kan du 
# ta bort passordet som argument til curl kommandoen 
#
# Merk at du må installere Cygwin først og installere curl og curl-lib. Nano anbefales som editor
# Cygwin - https://www.cygwin.com 
 
 
NAME=$(git branch | grep '*' | sed 's/* //') 
DESCRIPTION=$(git config branch."$NAME".description)
 
regex='TP ([0-9]+):*'
 
melding=$(git log -1 --pretty=format:%s)
 
echo "Viser melding her: "
echo $melding
 
tpnum=0
 
if [[ $melding =~ $regex ]]
then
 tpnum="${BASH_REMATCH[1]}"
        echo "TP number: $tpnum"
        curl -H "Content-Type: application/json" -X POST --data '{"Description":"'"$melding"'", "General": { "Id": "'"$tpnum"'"}}' https://someacme.tpondemand.com/api/v1/Comments?resultFormat=json -u TP_LOGON:TP_PASSWORD
 else 
  echo "Pusher ikke melding ut til Target Process. Bruk: Skriv TP TASKID: melding"
fi

Note that the curl command needs to be a one liner. To use this hook, just do some changes in your code and commit! git commit -m "TP 123: This is a checkin comment for the task with task Id 123 and will be shown in TP via a Git hook!" If you are working on a Windows system, you can download Cygwin (64-bits tested) and the libs curl and curl-lib. I like the Nano editor very much. Happy coding in Git and sharing your check in comments on TP! Pretty nifty to share progress with others!