Cryptography in Xamarin Forms

This article describes the Cryptography (Encryption & Decryption) mechanism to be implemented in Xamarin forms which can work for all the platforms - Windows, Android & ios.

Here, we are going to use PCLCrypto portable library which provides cryptographic APIs over algorithms implemented by the platform.
This library is a good choice for applications that require the assurance of high quality crypto implementations that can be reliable with in the operating system itself.

This API is designed to be similar to that found on WINRT or .Net Framework.  Below is the list of features available in PCLCrypto library.

• Cryptographically strong random number generator
• Symmetric and asymmetric encryption and signatures
• Key derivation
• Native crypto performance for each platform. This provides a 2-100X perf improvement for RSA on Android and iOS.
• Streaming encryption on WinRT, which goes beyond what the WinRT API itself offers (while still relying on the OS for the crypto    implementation).
• Support for multiple key formats (PKCS#1, PKCS#8, CAPI) on all platforms.

Create a Xamarin forms project and install the PCLCrypto library from nuget. Ensure to install this library for portable library and all the platforms too.

Now, common cryptographic code can be added to Portable library.

Create a helper class CryptoHelper.cs to add all cryptographic functions.

Generate a random byte array by passing the length which will be used as a salt while encryption and decryption. It would be best to have a unique salt value for each user and store with user record.

public
static byte[] CreateSalt(int lengthInBytes)
{
     return WinRTCrypto.CryptographicBuffer.GenerateRandom(lengthInBytes);
}

Derive a symmetric key from password, create a constant which will be used to generate a derived key along with salt.

const string SYMMETRICKEY = "FormsCryptography";

public
static byte[] CreateDerivedKey(string password, byte[] salt, int keyLengthInBytes = 32, int iterations = 1000)
{
            byte[] key = NetFxCrypto.DeriveBytes.GetBytes(password, salt, iterations, keyLengthInBytes);
            return key;
}

Now, perform AES encryption and decryption as below

public static string EncryptAes(string data, byte[] salt)
 {
             if (string.IsNullOrEmpty(data))
             {
                 return null;
            }

            byte[] key = CreateDerivedKey(SYMMETRICKEY, salt);

            ISymmetricKeyAlgorithmProvider aes = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
            ICryptographicKey symetricKey = aes.CreateSymmetricKey(key);
            var bytes = WinRTCrypto.CryptographicEngine.Encrypt(symetricKey, Encoding.UTF8.GetBytes(data));
            var encrptedText = Convert.ToBase64String(bytes);
             return encrptedText;
        }

public static string DecryptAes(string data, byte[] salt)
 {
             if (string.IsNullOrEmpty(data))
             {
                 return null;
            }

            byte[] key = CreateDerivedKey(SYMMETRICKEY, salt);

            ISymmetricKeyAlgorithmProvider aes = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
            ICryptographicKey symetricKey = aes.CreateSymmetricKey(key);
            var encryptedBytes = Convert.FromBase64String(data);
            var bytes = WinRTCrypto.CryptographicEngine.Decrypt(symetricKey, encryptedBytes);
            return Encoding.UTF8.GetString(bytes, 0, bytes.Length);
        }

Let’s use this helper class to encrypt and decrypt the text as below.  Now create a xaml view and place Entry to input the text to be encrypted and two buttons for Encryption and Decryption as below.

<
StackLayout>
    <Entry x:Name="txtText" Placeholder="Text to be Encrypted"></Entry>
    <Label x:Name="lblText"></Label>
    <Button x:Name="btnEncrypt" Text="Encrypt" ></Button>
    <Button x:Name="btnDecrypt" Text="Decrypt"></Button>
  </StackLayout>

private void BtnEncrypt_Clicked(object sender, EventArgs e)
{
             if (!string.IsNullOrEmpty(txtText.Text))
            {
                Salt = CryptoHelper.CreateSalt(16);
                TextToBeDecrypted = CryptoHelper.EncryptAes(txtText.Text, Salt);
             }
}

private void BtnDecrypt_Clicked(object sender, EventArgs e)
 {
             if (!string.IsNullOrEmpty(TextToBeDecrypted))
            {
                lblText.Text = CryptoHelper.DecryptAes(TextToBeDecrypted, Salt);
             }
}

Download the working sample

By Siva Jagan Dhulipalla   Popularity  (4437 Views)