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 Jan 11, 2015 · 15 revisions

Introduction

Most of the API is modeled after the WinRT crypto API. If you're familiar with that, you'll immediately feel at home with PCLCrypto. Instead of reusing the Windows.Security.Cryptography namespace, PCLCrypto functionality is available through the PCLCrypto.WinRTCrypto class.

In some cases, a .NET Framework API is emulated, which is available under the PCLCrypto.NetFxCrypto class.

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

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