Thursday 5 February 2015

Compare hash

the CryptographicBuffer class comes with an compare method that will allow you to compare hashes to see if the are the same, to start let's set up a UI

<Page
    x:Class="pc.encodingExample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:pc.encodingExample"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Page.Resources>
        <Style TargetType="TextBox">
            <Setter Property="Margin" Value="100 0 50 20"/>
            <Setter Property="TextWrapping" Value="Wrap"/>
            <Setter Property="FontSize" Value="24"/>
        </Style>
    </Page.Resources>
   
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="140"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="auto"/>
        </Grid.RowDefinitions>

        <TextBlock Grid.Column="1" Text="Hash Example" Style="{StaticResource HeaderTextBlockStyle}" VerticalAlignment="Center" Margin="100 0 0 0"/>

        <TextBox x:Name="HexInput_TXT" Header="HexIntput:" Grid.Row="1"/>
        <TextBox x:Name="Hex_TXT" Header="Hex:" IsReadOnly="True" Grid.Row="2"/>

        <TextBox x:Name="b64Input_TXT" Header="Base 64 Input:" Grid.Row="3"/>
        <TextBox x:Name="b64_TXT" Header="Base 64:" IsReadOnly="True" Grid.Row="4"/>

        <StackPanel Grid.Row="5" Orientation="Horizontal" Margin="100 0 0 20">
            <ComboBox x:Name="Hash_CB" />
            <Button x:Name="Hex_BTN" Content="Hex"  />
            <Button x:Name="b64_BTN" Content="64"  />
            <Button x:Name="Compare_BTN" Content="Compare"/>
        </StackPanel>
    </Grid>
</Page>


it should look like  so

next open up the codebehind, this time i'm not going to dive deep into the details, it's very similar to our previous example and the only thing really of note is the compare function, basically the code speaks for itself.

using System;
using Windows.Security.Cryptography;
using Windows.Security.Cryptography.Core;
using Windows.Storage.Streams;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace pc.hashCompareExanple
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            this.Hex_BTN.Click += Hex_BTN_Click;
            this.b64_BTN.Click += SixtyFour_BTN_Click;
            this.Compare_BTN.Click += Compare_BTN_Click;

            Hash_CB.ItemsSource = new string[] { "Md5", "Sha1", "Sha256", "Sha384", "Sha512" };
            Hash_CB.SelectedIndex = 0;
        }

        async void Compare_BTN_Click(object sender, RoutedEventArgs e)
        {
            IBuffer hexValue = CryptographicBuffer.DecodeFromHexString(Hex_TXT.Text);
            IBuffer b64Value = CryptographicBuffer.DecodeFromBase64String(b64_TXT.Text);

            //this is how the compare occurs
            if (CryptographicBuffer.Compare(hexValue, b64Value))
                await new MessageDialog("The buffers are equal").ShowAsync();
            else
                await new MessageDialog("The buffers are NOT equal").ShowAsync();
          
        }

        void SixtyFour_BTN_Click(object sender, RoutedEventArgs e)
        {
            HashAlgorithmProvider hashProvider = HashAlgorithmProvider.OpenAlgorithm(GetAlgorithmName());

            IBuffer binaryMessage = CryptographicBuffer.ConvertStringToBinary(this.b64Input_TXT.Text, BinaryStringEncoding.Utf8);
            IBuffer hashedMessage = hashProvider.HashData(binaryMessage);

            b64_TXT.Text = CryptographicBuffer.EncodeToBase64String(hashedMessage);
        }

        void Hex_BTN_Click(object sender, RoutedEventArgs e)
        {
            HashAlgorithmProvider hashProvider = HashAlgorithmProvider.OpenAlgorithm(GetAlgorithmName());

            IBuffer binaryMessage = CryptographicBuffer.ConvertStringToBinary(this.HexInput_TXT.Text, BinaryStringEncoding.Utf8);
            IBuffer hashedMessage = hashProvider.HashData(binaryMessage);

            Hex_TXT.Text = CryptographicBuffer.EncodeToHexString(hashedMessage);
        }


        string GetAlgorithmName()
        {
            switch (Hash_CB.SelectedValue.ToString())
            {
                case "Md5":
                    return HashAlgorithmNames.Md5;
                case "Sha1":
                    return HashAlgorithmNames.Sha1;
                case "Sha256":
                    return HashAlgorithmNames.Sha256;
                case "Sha384":
                    return HashAlgorithmNames.Sha384;
                case "Sha512":
                    return HashAlgorithmNames.Sha512;
            }

            return null;
        }
    }
}