This repository has been archived by the owner on Apr 1, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 55
Crypto Recipes
Andrew Arnott edited this page Jan 11, 2015
·
15 revisions
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.
// 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);
uint random = WinRTCrypto.CryptographicBuffer.GenerateRandomNumber();
uint randomFrom0To15 = WinRTCrypto.CryptographicBuffer.GenerateRandomNumber() % 16;
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`.
byte[] data;
var hasher = WinRTCrypto.HashAlgorithmProvider.OpenAlgorithm(HashAlgorithm.Sha1);
byte[] hash = hasher.HashData(data);
string hashBase64 = Convert.ToBase64String(hash);
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);
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);