public void TestHeader() { var transform = new TransformationRepresentative(typeof(AesCryptoManager), new byte[] { 1, 2, 3 }, CipherMode.CTS, PaddingMode.PKCS7, 128, 128); var key = new KeyRepresentative(typeof(Pbkdf2KeyDerive), 128UL, new byte[] { 1, 2, 3 }); var hmac = new HmacRepresentative(typeof(HMACMD5), new byte[] { 1, 2, 3 }); var data = new SymmetricCryptographicRepresentative(transform, key, hmac); var dataTwo = new SymmetricCryptographicRepresentative(); const string path = @"C:\Users\johnk\source\repos\EncryptionApp\localpath.txt"; data.WriteHeaderToFile(path); dataTwo.ReadHeaderFromFile(path); File.Delete(path); Assert.True(data.Equals(dataTwo)); }
/// <summary> /// TODO /// </summary> /// <param name="request"></param> /// <param name="password"></param> /// <param name="desiredKeyDerivationMilliseconds"></param> public void EncryptDataWithHeader(RequestStateRecord request, SecureString password, int desiredKeyDerivationMilliseconds) { if (request.Contract.InstanceKeyContract == null) { throw new ArgumentNullException(nameof(request)); } ((IProgress <int>) this._progress)?.Report(0); password.MakeReadOnly(); var salt = new byte[request.Contract.InstanceKeyContract.Value.SaltLengthBytes]; var iv = new byte[request.Contract.TransformationContract.InitializationVectorSizeBytes]; var rng = new RNGCryptoServiceProvider(); try { rng.GetBytes(salt); rng.GetBytes(iv); } catch (CryptographicException exception) { FileStatics.WriteToLogFile(exception); MessageBox.Show( "There was an error generating secure random numbers. Please try again - check log file for more details"); } var performanceDerivative = new PerformanceDerivative(request.Contract.InstanceKeyContract.Value.PerformanceDerivative); ((IProgress <int>) this._progress)?.Report(25); // Get the password if (password.Length == 0) { MessageBox.Show("You must enter a password"); ((IProgress <int>) this._progress)?.Report(0); return; } #if TRACE if (password.Length < App.This.CurrentSettings.MinPasswordLength) { MessageBox.Show("Password too short"); ((IProgress <int>)_progress)?.Report(0); return; } #endif GCHandle byteHandle = SecureStringConverter.SecureStringToKeyDerive(password, salt, performanceDerivative, request.Contract.InstanceKeyContract.Value.KeyAlgorithm, out KeyDerive keyDevice); ((IProgress <int>) this._progress)?.Report(35); HMAC hmacAlg = null; if (request.Contract.HmacContract != null) { // Create the algorithm using reflection hmacAlg = (HMAC)Activator.CreateInstance(request.Contract.HmacContract.Value.HashAlgorithm); } Aes aesAlgorithm = new AesCng { BlockSize = (int)request.Contract.TransformationContract.BlockSize, KeySize = (int)request.Contract.TransformationContract.KeySize, Mode = request.Contract.TransformationContract.CipherMode, Padding = request.Contract.TransformationContract.PaddingMode }; var @params = new object[] { 1024 * 1024 * 1024, aesAlgorithm }; var encryptor = (SymmetricCryptoManager)Activator.CreateInstance(request.Contract.TransformationContract.CryptoManager, @params); byte[] key = keyDevice.GetBytes((int)request.Contract.TransformationContract.KeySize / 8); Externals.ZeroMemory(byteHandle.AddrOfPinnedObject(), ((byte[])byteHandle.Target).Length); byteHandle.Free(); // Create a handle to the key to allow control of it GCHandle keyHandle = GCHandle.Alloc(key, GCHandleType.Pinned); // Encrypt the data to a temporary file encryptor.EncryptFileBytes(this._filePath, App.This.DataTempFile, key, iv); ((IProgress <int>) this._progress)?.Report(90); byte[] hash = null; if (request.Contract.HmacContract != null) { // Create the signature derived from the encrypted data and key byte[] signature = MessageAuthenticator.CreateHmac(App.This.DataTempFile, key, hmacAlg); // Set the signature correctly in the CryptographicRepresentative object hash = signature; } HmacRepresentative?hmac = request.Contract.HmacContract.HasValue ? new HmacRepresentative(request.Contract.HmacContract.Value.HashAlgorithm, hash) : (HmacRepresentative?)null; KeyRepresentative?keyRepresentative = new KeyRepresentative ( request.Contract.InstanceKeyContract.Value.KeyAlgorithm, request.Contract.InstanceKeyContract.Value.PerformanceDerivative, salt ); // Delete the key from memory for security Externals.ZeroMemory(keyHandle.AddrOfPinnedObject(), key.Length); keyHandle.Free(); var cryptographicInfo = new SymmetricCryptographicRepresentative ( new TransformationRepresentative ( request.Contract.TransformationContract.CryptoManager, iv, request.Contract.TransformationContract.CipherMode, request.Contract.TransformationContract.PaddingMode, request.Contract.TransformationContract.KeySize, request.Contract.TransformationContract.BlockSize ), keyRepresentative, hmac ); // Write the CryptographicRepresentative object to a file cryptographicInfo.WriteHeaderToFile(this._filePath); ((IProgress <int>) this._progress)?.Report(98); FileStatics.AppendToFile(this._filePath, App.This.DataTempFile); ((IProgress <int>) this._progress)?.Report(100); }