TripleDES Encryption in WinRT

2015, Mar 18    

A recent Universal Windows Store app I was working on needed a way to encrypt/decrypt data on the device. After looking around I couldn’t find the code I was looking for, so I crafted a bit of a helper class and I am including it here to help anybody else.

sidebar - data encryption and app security is a delicate area. I used this code in a proof of concept app so you may wish to double check it conforms to your projects security requirements. I’m not a security expert, but at the very least this can be a starter for 10

public static class TripleDesEncryptionHelper
{
	private static IBuffer GenerateKey()
    {
    	// Create a string that contains the algorithm name.
        string strAlgName = KeyDerivationAlgorithmNames.Pbkdf2Sha1;
        // Open the specified algorithm.
        KeyDerivationAlgorithmProvider objKdfProv = KeyDerivationAlgorithmProvider.OpenAlgorithm(strAlgName);
		// Specify the requested size, in bytes, of the derived key. 
        UInt32 targetSize = 24;
        // Create a buffer that contains the secret used during derivation.
        String strSecret = "SomeSecret"; //Change and move somewhere else
        IBuffer buffSecret = CryptographicBuffer.ConvertStringToBinary(strSecret, BinaryStringEncoding.Utf8);
        // Create a random salt value.
        String strSalt = "SaltValue"; //change and move somewhere else
        IBuffer buffSalt = CryptographicBuffer.ConvertStringToBinary(strSalt, BinaryStringEncoding.Utf8);
        // Specify the number of iterations to be used during derivation.
        UInt32 iterationCountIn = 5000;
        // Create the derivation parameters.
        KeyDerivationParameters pbkdf2Params = KeyDerivationParameters.BuildForPbkdf2(buffSalt, iterationCountIn);
        // Create a key from the secret value.
        CryptographicKey keyOriginal = objKdfProv.CreateKey(buffSecret);
        // Derive a key based on the original key and the derivation parameters.
           IBuffer keyDerived = CryptographicEngine.DeriveKeyMaterial(keyOriginal, pbkdf2Params, targetSize);
           return keyDerived;
        }
        
    public static string EncryptString(string ClearText)
    {
    	IBuffer plainBuffer = CryptographicBuffer.ConvertStringToBinary(ClearText, BinaryStringEncoding.Utf8);
        SymmetricKeyAlgorithmProvider symProvider = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.TripleDesEcbPkcs7);
        IBuffer tempbuf = GenerateKey();
        CryptographicKey symmKey = symProvider.CreateSymmetricKey(tempbuf)
        IBuffer resultBuffer = CryptographicEngine.Encrypt(symmKey, plainBuffer, null);
        string result = CryptographicBuffer.EncodeToBase64String(resultBuffer);
        return result;
     }
     
     public static string DecryptString(string EncryptedText)
     {
     	IBuffer plainBuffer = CryptographicBuffer.DecodeFromBase64String(EncryptedText);
         SymmetricKeyAlgorithmProvider symProvider = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.TripleDesEcbPkcs7);
         IBuffer tempbuf = GenerateKey();
         CryptographicKey symmKey = symProvider.CreateSymmetricKey(tempbuf);
         IBuffer resultBuffer = CryptographicEngine.Decrypt(symmKey, plainBuffer, null);
         string result = CryptographicBuffer.ConvertBinaryToString(BinaryStringEncoding.Utf8, resultBuffer);
         return result;
     }
}

For the provider, I have used TripleDesEcbPkcs7 which uses pkcs7 as the block size, which would work for any bock size from 1 to 255 bytes (but don’t quote me on that). You can change this by using any of the other algorithms in the SymmetricAlgorithmNames enumeration.

Obviously, you will want to change the secret and salt values and not use them as hard coded values.