Symmetric key encryption, also called secret key encryption, requires that the key used for encryption also be used for decryption. You can use a SymmetricKeyAlgorithmProvider object to specify a symmetric algorithm and create or import a key. You can use static methods on the CryptographicEngine class to encrypt and decrypt data by using the algorithm and key.
Under normal circumstances on top of the encryption key used, you would need to send vector values which is used as the initialization vector. However, for a simple scenario (e.g. you want to send a password value from the client to the server or vice-versa, and you don’t want to do a post with clear-text). You wouldn’t go through the trouble of carrying the IV buffer to the client side as well.
So here is a simple implementation that uses the AES encryption with ECB cipher mode and PKCS7 padding (PKCS #7 algorithms automatically pads the message to an appropriate length, so you don’t need to pad the cipher to a multiple of the block-size of the encryption algorithm you are using)
First step is to implement an MD5 hash generator which will be use to compute a hash from the encryption key that is being used.
private static IBuffer GetMD5Hash(string key)
{
// Convert the message string to binary data.
IBuffer buffUtf8Msg = CryptographicBuffer.ConvertStringToBinary(key, BinaryStringEncoding.Utf8);
// Create a HashAlgorithmProvider object.
HashAlgorithmProvider objAlgProv = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Md5);
// Hash the message.
IBuffer buffHash = objAlgProv.HashData(buffUtf8Msg);
// Verify that the hash length equals the length specified for the algorithm.
if (buffHash.Length != objAlgProv.HashLength)
{
throw new Exception("There was an error creating the hash");
}
return buffHash;
}
Once the key material is ready to be used to generate the symmetric key, we can go on with the encryption.
/// <summary>
/// Encrypt a string using dual encryption method. Returns an encrypted text.
/// </summary>
/// <param name="toEncrypt">String to be encrypted</param>
/// <param name="key">Unique key for encryption/decryption</param>m>
/// <returns>Returns encrypted string.</returns>
public static string Encrypt(string toEncrypt, string key)
{
try
{
// Get the MD5 key hash (you can as well use the binary of the key string)
var keyHash = GetMD5Hash(key);
// Create a buffer that contains the encoded message to be encrypted.
var toDecryptBuffer = CryptographicBuffer.ConvertStringToBinary(toEncrypt, BinaryStringEncoding.Utf8);
// Open a symmetric algorithm provider for the specified algorithm.
var aes = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesEcbPkcs7);
// Create a symmetric key.
var symetricKey = aes.CreateSymmetricKey(keyHash);
// The input key must be securely shared between the sender of the cryptic message
// and the recipient. The initialization vector must also be shared but does not
// need to be shared in a secure manner. If the sender encodes a message string
// to a buffer, the binary encoding method must also be shared with the recipient.
var buffEncrypted = CryptographicEngine.Encrypt(symetricKey, toDecryptBuffer, null);
// Convert the encrypted buffer to a string (for display).
// We are using Base64 to convert bytes to string since you might get unmatched characters
// in the encrypted buffer that we cannot convert to string with UTF8.
var strEncrypted = CryptographicBuffer.EncodeToBase64String(buffEncrypted);
return strEncrypted;
}
catch (Exception ex)
{
// MetroEventSource.Log.Error(ex.Message);
return "";
}
}
The decryption function is not any different in this case except for the fact that you would need to use Base64 conversion to convert the encrypted cipher to a buffer.
/// <summary>
/// Decrypt a string using dual encryption method. Return a Decrypted clear string
/// </summary>
/// <param name="cipherString">Encrypted string</param>
/// <param name="key">Unique key for encryption/decryption</param>
/// <returns>Returns decrypted text.</returns>
public static string Decrypt(string cipherString, string key)
{
try
{
// Get the MD5 key hash (you can as well use the binary of the key string)
var keyHash = GetMD5Hash(key);
// Create a buffer that contains the encoded message to be decrypted.
IBuffer toDecryptBuffer = CryptographicBuffer.DecodeFromBase64String(cipherString);
// Open a symmetric algorithm provider for the specified algorithm.
SymmetricKeyAlgorithmProvider aes = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesEcbPkcs7);
// Create a symmetric key.
var symetricKey = aes.CreateSymmetricKey(keyHash);
var buffDecrypted = CryptographicEngine.Decrypt(symetricKey, toDecryptBuffer, null);
string strDecrypted = CryptographicBuffer.ConvertBinaryToString(BinaryStringEncoding.Utf8, buffDecrypted);
return strDecrypted;
}
catch (Exception ex)
{
// MetroEventSource.Log.Error(ex.Message);
//throw;
return "";
}
}
And there it goes, a simple symmetric key encryption ready to be used in Windows Store Apps (aka Metro).
Happy coding everyone…
.jpg)
Pingback: Windows 8 Developer Links – 2012-10-04 | Dan Rigby
Pingback: Simple AES (Symmetric Key) Encryption in WinRT
worked like a wonder ! Thanks a lot !
hehe
glad it worked out for you..
How can I encrypt StorageFiles ?
what is “string key” in encrypt and decrypt methods?