goldytech
Published in

goldytech

Understanding Cryptography in WindowsRT

crypto

Security runs in my blood. After extensively working on cryptography on .net platform and have developed couple of mission critical apps. I was given the other challenge for an LOB app in WinRT platform. One of the requirements of the app was of cryptography. I researched it and learned a lot about it, so thought let me share the my knowledge with the community.

WHAT PLATFORM HAS TO OFFER

Let the readers get this straight, the WinRT platform is still under evolution , hence it does not offer the same number of apis that are available under .net platform. The platform will become more mature in future and you will see more convergence between the two platforms. There are two main api’s available which does most of heavy weight lifting. They are IBuffer, which marshal out the data. I would term it as an alternative to byte array available in .net and the other one is the static class CryptographicBuffer. I shall be talking about three aspects of cryptography

  1. Hashing
  2. Random Data
  3. Symmetric Encryption

HASHING

WinRT support MD5, SHA-1,SHA-256, SHA-384 and SHA-512 hashing algorithms. The code is pretty simple.

1: private async void BtnHashConvertTapped(object sender, TappedRoutedEventArgs e)2:        {3:            if (string.IsNullOrEmpty(this.TxtInput.Text))4:            {5:                return;6:            }7:8:            // get the raw input string9:            var textToBeHashed = this.TxtInput.Text;10:11:            // convert string into binary12:            var inputBuffer = CryptographicBuffer.ConvertStringToBinary(textToBeHashed, BinaryStringEncoding.Utf8);13:14:            // declare sha51215:            var sha512Hash = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha512);16:17:            // hash the binary data using SHA512 algorithm18:            var hashedData = sha512Hash.HashData(inputBuffer);19:20:            // encode the hashdata to Base64 format21:            var encodeToBase64String = CryptographicBuffer.EncodeToBase64String(hashedData);22:            var msgDialog = new MessageDialog(encodeToBase64String);23:24:            // show the output in message dialog25:            var msg = await msgDialog.ShowAsync();26:        }

After conversion of plain input string into binary, we select the algorithm that needs to be applied. The output of which is hashData which is of IBuffer type. And finally converting it back to Base64 format.

RANDOM DATA

It is quite common need of the enterprise apps to generate the random data. In WinRT platform this can be classified in two sections

  • Generating Random Number
1: /// <summary>2:         /// The generate random number.3:         /// </summary>4:         /// <param name="sender">5:         /// The sender.6:         /// </param>7:         /// <param name="e">8:         /// The e.9:         /// </param>10:         private async void GenerateRandomNumber(object sender, TappedRoutedEventArgs e)11:         {12:             // generate random number and show it is message dialog.13:             var msgDialog = new MessageDialog(CryptographicBuffer.GenerateRandomNumber().ToString());14:             var msg = await msgDialog.ShowAsync();15:16:         }

The GenerateRandomNumber method returns a 32 bit unsigned integer value.

  • Generating Random Byte Array
1: /// <summary>2:         /// Generates the random byte array3:         /// </summary>4:         /// <param name="sender">The sender</param>5:         /// <param name="e">The EventArgs</param>6:         void GenerateRandomArray(object sender, TappedRoutedEventArgs e)7:         {8:             uint len;9:             if (uint.TryParse(this.TxtLength.Text, out len))10:             {11:                 // generate the random byte array of specified length.12:                 var buffer = CryptographicBuffer.GenerateRandom(len);13:14:                 // convert the buffer (byte array) into hexadecimal format and show it in message dialog15:                 var msgDialog = new MessageDialog(CryptographicBuffer.EncodeToHexString(buffer));16:                 msgDialog.ShowAsync();17:             }18:             else19:             {20:                 // user inputted invalid number show the message and set back the focus21:                 new MessageDialog("Invalid number").ShowAsync();22:                 this.TxtLength.Focus(FocusState.Keyboard);23:             }24:         }

The above code demonstrates to generate random byte array of the specified length and converts back into hexadecimal format.

SYMMETERIC ENCRYPTION

In this type of encryption we have only one key for encryption and decryption. So we should have a key before hand. Apart from the key we also require the Initialization Vector , which does the job of randomizer. In our case we will be using 1024 bit key and 16 bit for IV. Again we will be using the GenerateRandom method to generate these values. Both these binary values will be converted back to Hex format. Let us dive in code and see it in action.

1: /// <summary>2:         /// Generates a random 1024 bit key3:         /// </summary>4:         /// <returns>A Hex format key</returns>5:         private static string GetKey()6:         {7:             // generate 1024 bits key8:             var buffer = CryptographicBuffer.GenerateRandom(1024);9:             return CryptographicBuffer.EncodeToHexString(buffer);10:         }11:12:         /// <summary>13:         /// The get initialization vector.14:         /// </summary>15:         /// <returns>16:         /// The <see cref="string"/>.17:         /// </returns>18:         private static string GetInitializationVector()19:         {20:             // a 16 bit random binary value21:             var buffer = CryptographicBuffer.GenerateRandom(16);22:             return CryptographicBuffer.EncodeToHexString(buffer);23:         }

Code to Encrypt

1: /// <summary>2:        /// The encrypt.3:        /// </summary>4:        /// <param name="sender">5:        /// The sender.6:        /// </param>7:        /// <param name="e">8:        /// The e.9:        /// </param>10:        private void Encrypt(object sender, TappedRoutedEventArgs e)11:        {12:            if (string.IsNullOrEmpty(this.TxtPlain.Text))13:            {14:                return;15:            }16:17:            // convert plain text to binary18:            var input = CryptographicBuffer.ConvertStringToBinary(this.TxtPlain.Text, BinaryStringEncoding.Utf8);19:            var iv = CryptographicBuffer.DecodeFromBase64String(this.IV);20:21:            // select the appropriate algorithm22:            var encryptor = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7);23:24:            // get the key25:            var key = encryptor.CreateSymmetricKey(CryptographicBuffer.DecodeFromBase64String(this.symmetricKey));26:27:            // do the encryption28:            var encryptedText = CryptographicEngine.Encrypt(key, input, iv);29:30:            // convert the encrypted text into hex format and show it in textbox31:            this.TxtCipher.Text = CryptographicBuffer.EncodeToHexString(encryptedText);32:        }

Code to Decrypt

1: /// <summary>2:         /// The decrypt.3:         /// </summary>4:         /// <param name="sender">5:         /// The sender.6:         /// </param>7:         /// <param name="e">8:         /// The e.9:         /// </param>10:         private void Decrypt(object sender, TappedRoutedEventArgs e)11:         {12:             if (!string.IsNullOrEmpty(this.TxtCipher.Text))13:             {14:                 // as the encrypted string is in hex format decode it and convert back to binary15:                 var input = CryptographicBuffer.DecodeFromHexString(this.TxtCipher.Text);16:17:                 // decode the initialization vector18:                 var iv = CryptographicBuffer.DecodeFromBase64String(this.IV);19:20:                 // specify the algorithm use the same one which was used with encryption21:                 var decryptor = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7);22:23:                 // get the key , same should be used which was used for encryption24:                 var key = decryptor.CreateSymmetricKey(CryptographicBuffer.DecodeFromBase64String(this.symmetricKey));25:26:                 // Do the decryption27:                 var decryptedText = CryptographicEngine.Decrypt(key, input, iv);28:                 this.TxtPlain.Text = CryptographicBuffer.ConvertBinaryToString(BinaryStringEncoding.Utf8, decryptedText);29:             }30:             else31:             {32:                 new MessageDialog("First encrypt").ShowAsync();33:             }34:         }

CLOSURE

I talked about using the cryptography methods when you are developing a WinRT app. Apart from this operating system also has a built in support for bit locker (Only available in Pro and Enterprise versions) which helps to preserve the enterprise data and can be remotely wiped off with the Mobile Device Management Software like Windows InTune. Last but not least when your app depends on the web services it is always good practice to invoke them securely over SSL. The source code accompanying this post article is available on my GitHub account. Do share your valuable feedback.

--

--

A software geek and technocrat passionate about all emerging technologies. Desire to become a tech unicorn. Open Source Software Enthuiast

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store