Configuration for common crypto operations.
        /// <summary>
        /// Creates a web safe base64 thumbprint of some buffer.
        /// </summary>
        /// <param name="cryptoProvider">The crypto provider.</param>
        /// <param name="buffer">The buffer.</param>
        /// <returns>A string representation of a hash of the <paramref name="buffer"/>.</returns>
        public static string CreateWebSafeBase64Thumbprint(this CryptoSettings cryptoProvider, byte[] buffer)
        {
            Requires.NotNull(cryptoProvider, "cryptoProvider");
            Requires.NotNull(buffer, "buffer");

            var hasher = WinRTCrypto.HashAlgorithmProvider.OpenAlgorithm(cryptoProvider.SymmetricHashAlgorithm);
            var hash = hasher.HashData(buffer);
            return Utilities.ToBase64WebSafe(hash);
        }
        /// <summary>
        /// Symmetrically encrypts the specified buffer using a randomly generated key.
        /// </summary>
        /// <param name="cryptoProvider">The crypto provider.</param>
        /// <param name="data">The data to encrypt.</param>
        /// <param name="encryptionVariables">Optional encryption variables to use; or <c>null</c> to use randomly generated ones.</param>
        /// <returns>
        /// The result of the encryption.
        /// </returns>
        public static SymmetricEncryptionResult Encrypt(this CryptoSettings cryptoProvider, byte[] data, SymmetricEncryptionVariables encryptionVariables = null)
        {
            Requires.NotNull(data, "data");

            encryptionVariables = ThisOrNewEncryptionVariables(cryptoProvider, encryptionVariables);
            var symmetricKey = CryptoSettings.SymmetricAlgorithm.CreateSymmetricKey(encryptionVariables.Key);
            var cipherTextBuffer = WinRTCrypto.CryptographicEngine.Encrypt(symmetricKey, data, encryptionVariables.IV);
            return new SymmetricEncryptionResult(encryptionVariables, cipherTextBuffer);
        }
 /// <summary>
 /// Returns the specified encryption variables if they are non-null, or generates new ones.
 /// </summary>
 /// <param name="cryptoProvider">The crypto provider.</param>
 /// <param name="encryptionVariables">The encryption variables.</param>
 /// <returns>
 /// A valid set of encryption variables.
 /// </returns>
 private static SymmetricEncryptionVariables ThisOrNewEncryptionVariables(CryptoSettings cryptoProvider, SymmetricEncryptionVariables encryptionVariables)
 {
     if (encryptionVariables == null)
     {
         return NewSymmetricEncryptionVariables(cryptoProvider);
     }
     else
     {
         Requires.Argument(encryptionVariables.Key.Length == cryptoProvider.SymmetricKeySize / 8, "key", "Incorrect length.");
         Requires.Argument(encryptionVariables.IV.Length == CryptoSettings.SymmetricAlgorithm.BlockLength, "iv", "Incorrect length.");
         return encryptionVariables;
     }
 }
Beispiel #4
0
        /// <summary>
        /// Creates a signed address book entry that describes the public information in this endpoint.
        /// </summary>
        /// <param name="cryptoServices">The crypto services to use for signing the address book entry.</param>
        /// <returns>The address book entry.</returns>
        public AddressBookEntry CreateAddressBookEntry(CryptoSettings cryptoServices)
        {
            Requires.NotNull(cryptoServices, "cryptoServices");

            var ms     = new MemoryStream();
            var writer = new BinaryWriter(ms);
            var entry  = new AddressBookEntry();

            writer.SerializeDataContract(this.PublicEndpoint);
            writer.Flush();
            entry.SerializedEndpoint = ms.ToArray();
            entry.Signature          = WinRTCrypto.CryptographicEngine.Sign(this.SigningKey, entry.SerializedEndpoint);
            return(entry);
        }
        /// <summary>
        /// Symmetrically decrypts a stream.
        /// </summary>
        /// <param name="cryptoProvider">The crypto provider.</param>
        /// <param name="ciphertext">The stream of ciphertext to decrypt.</param>
        /// <param name="plaintext">The stream to receive the plaintext.</param>
        /// <param name="encryptionVariables">The key and IV to use.</param>
        /// <param name="cancellationToken">A cancellation token.</param>
        /// <returns>
        /// A task that represents the asynchronous operation.
        /// </returns>
        public static async Task DecryptAsync(this CryptoSettings cryptoProvider, Stream ciphertext, Stream plaintext, SymmetricEncryptionVariables encryptionVariables, CancellationToken cancellationToken = default(CancellationToken))
        {
            Requires.NotNull(ciphertext, "ciphertext");
            Requires.NotNull(plaintext, "plaintext");
            Requires.NotNull(encryptionVariables, "encryptionVariables");

            var key = CryptoSettings.SymmetricAlgorithm.CreateSymmetricKey(encryptionVariables.Key);
            using (var decryptor = WinRTCrypto.CryptographicEngine.CreateDecryptor(key, encryptionVariables.IV))
            {
                var cryptoStream = new CryptoStream(plaintext, decryptor, CryptoStreamMode.Write);
                await ciphertext.CopyToAsync(cryptoStream, 4096, cancellationToken).ConfigureAwait(false);
                cryptoStream.FlushFinalBlock();
            }
        }
        /// <summary>
        /// Computes the hash of the specified buffer and checks for a match to an expected hash.
        /// </summary>
        /// <param name="cryptoProvider">The crypto provider.</param>
        /// <param name="data">The data to hash.</param>
        /// <param name="expectedHash">The expected hash.</param>
        /// <param name="hashAlgorithm">The hash algorithm.</param>
        /// <returns>
        ///   <c>true</c> if the hashes came out equal; <c>false</c> otherwise.
        /// </returns>
        internal static bool IsHashMatchWithTolerantHashAlgorithm(this CryptoSettings cryptoProvider, byte[] data, byte[] expectedHash, HashAlgorithm? hashAlgorithm)
        {
            Requires.NotNull(cryptoProvider, "cryptoProvider");
            Requires.NotNull(data, "data");
            Requires.NotNull(expectedHash, "expectedHash");

            if (!hashAlgorithm.HasValue)
            {
                hashAlgorithm = Utilities.GuessHashAlgorithmFromLength(expectedHash.Length);
            }

            var hasher = WinRTCrypto.HashAlgorithmProvider.OpenAlgorithm(hashAlgorithm.Value);
            byte[] actualHash = hasher.HashData(data);
            return Utilities.AreEquivalent(expectedHash, actualHash);
        }
Beispiel #7
0
        /// <summary>
        /// Creates a signed address book entry that describes the public information in this endpoint.
        /// </summary>
        /// <param name="cryptoServices">The crypto services to use for signing the address book entry.</param>
        /// <returns>The address book entry.</returns>
        public AddressBookEntry CreateAddressBookEntry(CryptoSettings cryptoServices)
        {
            Requires.NotNull(cryptoServices, "cryptoServices");

            var ms = new MemoryStream();
            var writer = new BinaryWriter(ms);
            var entry = new AddressBookEntry();
            writer.SerializeDataContract(this.PublicEndpoint);
            writer.Flush();
            entry.SerializedEndpoint = ms.ToArray();
            entry.Signature = WinRTCrypto.CryptographicEngine.Sign(this.SigningKey, entry.SerializedEndpoint);
            return entry;
        }
 /// <summary>
 /// Generates a new set of encryption variables.
 /// </summary>
 /// <param name="cryptoProvider">The crypto provider.</param>
 /// <returns>
 /// A set of encryption variables.
 /// </returns>
 private static SymmetricEncryptionVariables NewSymmetricEncryptionVariables(CryptoSettings cryptoProvider)
 {
     byte[] key = WinRTCrypto.CryptographicBuffer.GenerateRandom(cryptoProvider.SymmetricKeySize / 8);
     byte[] iv = WinRTCrypto.CryptographicBuffer.GenerateRandom(CryptoSettings.SymmetricAlgorithm.BlockLength);
     return new SymmetricEncryptionVariables(key, iv);
 }
 /// <summary>
 /// Symmetrically decrypts a buffer using the specified key.
 /// </summary>
 /// <param name="cryptoProvider">The crypto provider.</param>
 /// <param name="data">The encrypted data and the key and IV used to encrypt it.</param>
 /// <returns>
 /// The decrypted buffer.
 /// </returns>
 public static byte[] Decrypt(this CryptoSettings cryptoProvider, SymmetricEncryptionResult data)
 {
     var symmetricKey = CryptoSettings.SymmetricAlgorithm.CreateSymmetricKey(data.Key);
     return WinRTCrypto.CryptographicEngine.Decrypt(symmetricKey, data.Ciphertext, data.IV);
 }