Skip to content
This repository has been archived by the owner on Apr 1, 2024. It is now read-only.

Crypto Recipes

Andrew Arnott edited this page Jun 29, 2015 · 15 revisions

If it isn't documented here, there's a very good chance it is still available in the library. The documentation below is incomplete.

A couple of very common mistakes made by would-be cryptographers:

  1. Using a key that is not one of the allowed sizes. What are the allowed sizes?

  2. Picking an algorithm that does not include padding and then not supplying data that exactly fills a cipher block. Which algorithms include padding?

Create a buffer filled with cryptographically strong random data
// WinRT-like API
uint length = 15;
byte[] cryptoRandomBuffer = WinRTCrypto.CryptographicBuffer.GenerateRandom(length);

// .NET Framework-like API
byte[] cryptoRandomBuffer = new byte[15];
NetFxCrypto.RandomNumberGenerator.GetBytes(cryptoRandomBuffer);
Generate a random number
uint random = WinRTCrypto.CryptographicBuffer.GenerateRandomNumber();
uint randomFrom0To15 = WinRTCrypto.CryptographicBuffer.GenerateRandomNumber() % 16;
Derive a symmetric key from a password

To use crypto APIs with a user-supplied password, you must at least convert the password into a byte buffer. But it's more secure to run it through a key derivation algorithm, using this technique:

string password; // comes in from the user.
byte[] salt; // best initialized to a unique value for each user, and stored with the user record
int iterations = 5000; // higher makes brute force attacks more expensive
int keyLengthInBytes;
byte[] key = NetFxCrypto.DeriveBytes.GetBytes(password, salt, iterations, keyLengthInBytes);

// A similar technique is possible using WinRT-emulated API via the `WinRTCrypto.KeyDerivationAlgorithmProvider`.
Get the hash for a buffer (SHA1, SHA256, etc.)
byte[] data;
var hasher = WinRTCrypto.HashAlgorithmProvider.OpenAlgorithm(HashAlgorithm.Sha1);
byte[] hash = hasher.HashData(data);
string hashBase64 = Convert.ToBase64String(hash);
Get the MAC for a buffer (HMAC-SHA1, HMAC-SHA256, etc.)
byte[] keyMaterial;
byte[] data;
var algorithm = WinRTCrypto.MacAlgorithmProvider.OpenAlgorithm(MacAlgorithm.HmacSha1);
CryptographicHash hasher = algorithm.CreateHash(keyMaterial);
hasher.Append(data);
byte[] mac = hasher.GetValueAndReset();
string macBase64 = Convert.ToBase64String(mac);
Perform AES encryption/decryption
byte[] keyMaterial;
byte[] data;
var provider = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
var key = provider.CreateSymmetricKey(keyMaterial);
byte[] iv = null; // this is optional, but must be the same for both encrypting and decrypting
byte[] cipherText = WinRTCrypto.CryptographicEngine.Encrypt(key, data, iv);
byte[] plainText = WinRTCrypto.CryptographicEngine.Decrypt(key, cipherText, iv);
Clone this wiki locally