private async Task PlayAliceRoleAsync(ICryptographicKey ownSigningKey, ICryptographicKey othersSigningPublicKey, Stream channel, CancellationToken cancellationToken) { // Create ephemeral ECDH key pair, to prepare for the symmetric encryption key exchange. using (var ecdhKeyPair = NetFxCrypto.ECDiffieHellman.Create()) { // Alice receives Bob's ECDH public key and signature. byte[] bobPublicDH = await ReadAsync(channel, cancellationToken); byte[] bobSignedDH = await ReadAsync(channel, cancellationToken); // Alice verifies Bob's signature to be sure it's his key. Assert.IsTrue(WinRTCrypto.CryptographicEngine.VerifySignature(othersSigningPublicKey, bobPublicDH, bobSignedDH)); // Alice replies to Bob's public key by transmitting her own public key and signature. var ecdhPublicKey = ecdhKeyPair.PublicKey.ToByteArray(); await WriteAsync(channel, ecdhPublicKey, cancellationToken); byte[] ecdhPublicKeySignature = WinRTCrypto.CryptographicEngine.Sign(ownSigningKey, ecdhPublicKey); await WriteAsync(channel, ecdhPublicKeySignature, cancellationToken); // Derive a shared secret with Bob by combining Alice's private key with Bob's public key. var bobDHPK = NetFxCrypto.ECDiffieHellmanCngPublicKey.FromByteArray(bobPublicDH); byte[] encryptionKeyMaterial = ecdhKeyPair.DeriveKeyMaterial(bobDHPK); var symmetricEncryptionKey = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7) .CreateSymmetricKey(encryptionKeyMaterial); // Alice also adds a secret message. using (var aes = CryptoStream.WriteTo(channel, WinRTCrypto.CryptographicEngine.CreateEncryptor(symmetricEncryptionKey))) { await aes.WriteAsync(SecretMessage, 0, SecretMessage.Length, cancellationToken); } channel.Dispose(); } }
public void WriteTo_InvalidInputs() { ExceptionAssert.Throws <ArgumentNullException>( () => CryptoStream.WriteTo(null, new MockCryptoTransform(5))); ExceptionAssert.Throws <ArgumentException>( () => CryptoStream.WriteTo(Stream.Null)); ExceptionAssert.Throws <ArgumentException>( () => CryptoStream.WriteTo(Stream.Null, null)); }
public void WriteTo() { var t1 = new MockCryptoTransform(6); var t2 = new MockCryptoTransform(9); var ms = new MemoryStream(); using (var cryptoStream = CryptoStream.WriteTo(ms, t1, t2)) { cryptoStream.Write(Encoding.UTF8.GetBytes("abcdefghijkl"), 0, 12); } Assert.AreEqual("--abcdef-g_hijkl_ZZ", Encoding.UTF8.GetString(ms.ToArray())); }
public async Task <string> ComputeMD5Async(IFile file) { using (var inputStream = await file.OpenAsync(PCLStorage.FileAccess.Read)) using (var hasher = WinRTCrypto.HashAlgorithmProvider.OpenAlgorithm(HashAlgorithm.Md5).CreateHash()) using (var nullStream = Stream.Null) { using (var cryptoStream = CryptoStream.WriteTo(nullStream, hasher)) { await inputStream.CopyToAsync(cryptoStream); var hashBytes = hasher.GetValueAndReset(); var hashString = BitConverter.ToString(hashBytes); return(hashString.Replace("-", string.Empty)); } } }
static async Task CryptoTransformFileAsync(string sourcePath, string destinationPath, ICryptoTransform[] transforms, CancellationToken cancellationToken) { const int BufferSize = 4096; using (var sourceStream = new FileStream(sourcePath, FileMode.Open, FileAccess.Read, FileShare.Read, BufferSize, useAsync: true)) { using (var destinationStream = new FileStream(destinationPath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None, BufferSize, useAsync: true)) { using (var cryptoStream = CryptoStream.WriteTo(destinationStream, transforms)) { await sourceStream.CopyToAsync(cryptoStream, BufferSize, cancellationToken); await cryptoStream.FlushAsync(cancellationToken); cryptoStream.FlushFinalBlock(); } } } }
public void CreateEncryptor_SymmetricEncryptionEquivalence() { foreach (SymmetricAlgorithm symmetricAlgorithm in Enum.GetValues(typeof(SymmetricAlgorithm))) { try { var algorithmProvider = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(symmetricAlgorithm); uint keyLength = GetKeyLength(symmetricAlgorithm, algorithmProvider); byte[] keyMaterial = WinRTCrypto.CryptographicBuffer.GenerateRandom(keyLength); var key1 = algorithmProvider.CreateSymmetricKey(keyMaterial); var key2 = algorithmProvider.CreateSymmetricKey(keyMaterial); // create a second key so that streaming ciphers will be produce the same result when executed the second time var iv = symmetricAlgorithm.UsesIV() ? WinRTCrypto.CryptographicBuffer.GenerateRandom((uint)algorithmProvider.BlockLength) : null; for (int dataLengthFactor = 1; dataLengthFactor <= 3; dataLengthFactor++) { var data = WinRTCrypto.CryptographicBuffer.GenerateRandom((uint)(dataLengthFactor * algorithmProvider.BlockLength)); var expected = WinRTCrypto.CryptographicEngine.Encrypt(key1, data, iv); var encryptor = WinRTCrypto.CryptographicEngine.CreateEncryptor(key2, iv); var actualStream = new MemoryStream(); using (var cryptoStream = CryptoStream.WriteTo(actualStream, encryptor)) { cryptoStream.Write(data, 0, data.Length); cryptoStream.FlushFinalBlock(); byte[] actual = actualStream.ToArray(); Assert.AreEqual( Convert.ToBase64String(expected), Convert.ToBase64String(actual)); } } Debug.WriteLine("Algorithm {0} passed.", symmetricAlgorithm); } catch (NotSupportedException) { Debug.WriteLine("Algorithm {0} is not supported on this platform.", symmetricAlgorithm); } } }
public void CreateEncryptor_SymmetricEncryptionEquivalence(SymmetricAlgorithmName name, SymmetricAlgorithmMode mode, SymmetricAlgorithmPadding padding) { Skip.If(!name.IsBlockCipher() && padding != SymmetricAlgorithmPadding.None, "By design - streaming ciphers need no padding."); var algorithmProvider = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(name, mode, padding); int keyLength = GetKeyLength(name, algorithmProvider); byte[] keyMaterial = WinRTCrypto.CryptographicBuffer.GenerateRandom(keyLength); var key1 = algorithmProvider.CreateSymmetricKey(keyMaterial); var key2 = algorithmProvider.CreateSymmetricKey(keyMaterial); // create a second key so that streaming ciphers will be produce the same result when executed the second time var iv = mode.UsesIV() ? WinRTCrypto.CryptographicBuffer.GenerateRandom(algorithmProvider.BlockLength) : null; float incrementBy = padding == SymmetricAlgorithmPadding.None ? 1 : 0.5f; for (float dataLengthFactor = 1; dataLengthFactor <= 3; dataLengthFactor += incrementBy) { var data = WinRTCrypto.CryptographicBuffer.GenerateRandom((int)(dataLengthFactor * algorithmProvider.BlockLength)); var expected = WinRTCrypto.CryptographicEngine.Encrypt(key1, data, iv); var encryptor = WinRTCrypto.CryptographicEngine.CreateEncryptor(key2, iv); var actualStream = new MemoryStream(); using (var cryptoStream = CryptoStream.WriteTo(actualStream, encryptor)) { // Write it in smaller than block length chunks so we're exercising more product code. int chunkSize = Math.Max(1, (int)(data.Length / Math.Max(1, dataLengthFactor + 1))); for (int dataOffset = 0; dataOffset < data.Length; dataOffset += chunkSize) { cryptoStream.Write(data, dataOffset, Math.Min(chunkSize, data.Length - dataOffset)); } cryptoStream.FlushFinalBlock(); byte[] actual = actualStream.ToArray(); Assert.Equal( Convert.ToBase64String(expected), Convert.ToBase64String(actual)); } } }