private App() { // Run startup try { this.PerformanceDerivative = new PerformanceDerivative(); this.BuildFileSystem(); } catch (CryptographicException e) { FileStatics.WriteToLogFile(e); MessageBox.Show( "Startup exception occured during creation of the performance derivative - Check log file"); throw; } catch (IOException e) { FileStatics.WriteToLogFile(e); MessageBox.Show( "Startup exception occured during creation/validation of the file system - Check log file"); throw; } This = this; this.CurrentSettings = new AppSettings(); }
private void DecryptDataWithHeader(CryptographicInfo cryptographicInfo, SecureString password, string filePath) { #if DEBUG Stopwatch watch = Stopwatch.StartNew(); #endif KeyDerive keyDevice; #if DEBUG Console.WriteLine(Encryption_App.Resources.MainWindow_DecryptDataWithHeader_Start_time__ + watch.ElapsedMilliseconds); #endif // Load the assemblies necessary for reflection Assembly securityAsm = Assembly.LoadFile(Path.Combine(RuntimeEnvironment.GetRuntimeDirectory(), "System.Security.dll")); Assembly coreAsm = Assembly.LoadFile(Path.Combine(RuntimeEnvironment.GetRuntimeDirectory(), "System.Core.dll")); #if DEBUG Console.WriteLine(Encryption_App.Resources.MainWindow_DecryptDataWithHeader_Assembly_loaded_time__ + watch.ElapsedMilliseconds); #endif var performanceDerivative = new PerformanceDerivative(cryptographicInfo.InstanceKeyCreator.PerformanceDerivative); // Marshal the secure string to a managed string using (password) { // Turn the secure string into a string to pass it into keyDevice for the shortest interval possible IntPtr valuePtr = IntPtr.Zero; try { valuePtr = Marshal.SecureStringToGlobalAllocUnicode(password); // Create an object array of parameters var parameters = new object[] { Marshal.PtrToStringUni(valuePtr), cryptographicInfo.InstanceKeyCreator.salt, null }; var tempTransformationDevice = (KeyDerive)Activator.CreateInstance(Type.GetType(cryptographicInfo.InstanceKeyCreator.root_HashAlgorithm) ?? securityAsm.GetType(cryptographicInfo.InstanceKeyCreator.root_HashAlgorithm) ?? coreAsm.GetType(cryptographicInfo.InstanceKeyCreator.root_HashAlgorithm)); tempTransformationDevice.TransformPerformance(performanceDerivative, 2000); // TODO put in crypto-info parameters[2] = tempTransformationDevice.PerformanceValues; keyDevice = (KeyDerive)Activator.CreateInstance(Type.GetType(cryptographicInfo.InstanceKeyCreator.root_HashAlgorithm) ?? securityAsm.GetType(cryptographicInfo.InstanceKeyCreator.root_HashAlgorithm) ?? coreAsm.GetType(cryptographicInfo.InstanceKeyCreator.root_HashAlgorithm), parameters); } finally { // Destroy the unmanaged string Marshal.ZeroFreeGlobalAllocUnicode(valuePtr); } } #if DEBUG Console.WriteLine(Encryption_App.Resources.MainWindow_DecryptDataWithHeader_Password_managed_time__ + watch.ElapsedMilliseconds); #endif HMAC hmacAlg = null; if (cryptographicInfo.Hmac != null) { hmacAlg = (HMAC)Activator.CreateInstance(Type.GetType(cryptographicInfo.Hmac.HashAlgorithm) ?? securityAsm.GetType(cryptographicInfo.Hmac.HashAlgorithm) ?? coreAsm.GetType(cryptographicInfo.Hmac.HashAlgorithm)); } #if DEBUG Console.WriteLine(Encryption_App.Resources.MainWindow_DecryptDataWithHeader_Object_built_time__ + watch.ElapsedMilliseconds); #endif var decryptor = (SymmetricCryptoManager)Activator.CreateInstance(Type.GetType(cryptographicInfo.CryptoManager) ?? securityAsm.GetType(cryptographicInfo.CryptoManager) ?? coreAsm.GetType(cryptographicInfo.CryptoManager)); #if DEBUG Console.WriteLine(Encryption_App.Resources.MainWindow_DecryptDataWithHeader_Object_built_time__ + watch.ElapsedMilliseconds); #endif FileStatics.RemovePrependData(filePath, _headerLessTempFile, cryptographicInfo.HeaderLength); #if DEBUG Console.WriteLine(Encryption_App.Resources.MainWindow_DecryptDataWithHeader_Header_removed_time__ + watch.ElapsedMilliseconds); #endif byte[] key = keyDevice.GetBytes((int)cryptographicInfo.EncryptionModeInfo.KeySize / 8); GCHandle gch = GCHandle.Alloc(key, GCHandleType.Pinned); var isVerified = false; if (cryptographicInfo.Hmac != null) { // Check if the file and key make the same HMAC isVerified = MessageAuthenticator.VerifyHmac(_headerLessTempFile, key, cryptographicInfo.Hmac.root_Hash, hmacAlg); } #if DEBUG Console.WriteLine(Encryption_App.Resources.MainWindow_DecryptDataWithHeader_HMAC_verified_time__ + watch.ElapsedMilliseconds); #endif // If that didn't succeed, the file has been tampered with if (cryptographicInfo.Hmac != null && !isVerified) { throw new CryptographicException("File could not be verified - may have been tampered, or the password is incorrect"); } // Try decrypting the remaining data try { #if DEBUG Console.WriteLine(Encryption_App.Resources.MainWindow_DecryptDataWithHeader_Pre_decryption_time__ + watch.ElapsedMilliseconds); #endif decryptor.DecryptFileBytes(_headerLessTempFile, _dataTempFile, key, cryptographicInfo.EncryptionModeInfo.InitializationVector); StepDecryptStrings(); #if DEBUG Console.WriteLine(Encryption_App.Resources.MainWindow_DecryptDataWithHeader_Post_decryption_time__ + watch.ElapsedMilliseconds); #endif // Move the file to the original file location File.Copy(_dataTempFile, filePath, true); #if DEBUG Console.WriteLine(Encryption_App.Resources.MainWindow_DecryptDataWithHeader_File_copied_time__ + watch.ElapsedMilliseconds); #endif MessageBox.Show("Successfully Decrypted"); } catch (CryptographicException) { MessageBox.Show("Wrong password or corrupted file"); } finally { // Delete the key from memory for security ZeroMemory(gch.AddrOfPinnedObject(), key.Length); gch.Free(); GC.Collect(); } }
private void EncryptDataWithHeader(CryptographicInfo cryptographicInfo, SecureString password, string filePath) { #if DEBUG Stopwatch watch = Stopwatch.StartNew(); #endif // Forward declaration of the device used to derive the key KeyDerive keyDevice = null; // Load the assemblies necessary for reflection Assembly securityAsm = Assembly.LoadFile(Path.Combine(RuntimeEnvironment.GetRuntimeDirectory(), "System.Security.dll")); Assembly coreAsm = Assembly.LoadFile(Path.Combine(RuntimeEnvironment.GetRuntimeDirectory(), "System.Core.dll")); var performanceDerivative = new PerformanceDerivative(cryptographicInfo.InstanceKeyCreator.PerformanceDerivative); // Get the password using (password) { if (password.Length == 0) { EncryptOutput.Content = "You must enter a password"; return; } if (password.Length < 4) { EncryptOutput.Content = "Password to short"; return; } // Turn the secure string into a string to pass it into keyDevice for the shortest interval possible IntPtr valuePtr = IntPtr.Zero; try { valuePtr = Marshal.SecureStringToGlobalAllocUnicode(password); // Create an object array of parameters var parameters = new object[] { Marshal.PtrToStringUni(valuePtr), cryptographicInfo.InstanceKeyCreator.salt, null }; var tempTransformationDevice = (KeyDerive)Activator.CreateInstance(Type.GetType(cryptographicInfo.InstanceKeyCreator.root_HashAlgorithm) ?? securityAsm.GetType(cryptographicInfo.InstanceKeyCreator.root_HashAlgorithm) ?? coreAsm.GetType(cryptographicInfo.InstanceKeyCreator.root_HashAlgorithm)); tempTransformationDevice.TransformPerformance(performanceDerivative, 2000UL); #if DEBUG Console.WriteLine(Encryption_App.Resources.MainWindow_EncryptDataWithHeader_Iteration_value__ + tempTransformationDevice.PerformanceValues); #endif parameters[2] = tempTransformationDevice.PerformanceValues; keyDevice = (KeyDerive)Activator.CreateInstance(Type.GetType(cryptographicInfo.InstanceKeyCreator.root_HashAlgorithm) ?? securityAsm.GetType(cryptographicInfo.InstanceKeyCreator.root_HashAlgorithm) ?? coreAsm.GetType(cryptographicInfo.InstanceKeyCreator.root_HashAlgorithm), parameters); } finally { // Destroy the managed string Marshal.ZeroFreeGlobalAllocUnicode(valuePtr); } } HMAC hmacAlg = null; if (cryptographicInfo.Hmac != null) { // Create the algorithm using reflection hmacAlg = (HMAC)Activator.CreateInstance(Type.GetType(cryptographicInfo.Hmac.HashAlgorithm) ?? securityAsm.GetType(cryptographicInfo.Hmac .HashAlgorithm) ?? coreAsm.GetType(cryptographicInfo.Hmac.HashAlgorithm)); } var encryptor = (SymmetricCryptoManager)Activator.CreateInstance(Type.GetType(cryptographicInfo.CryptoManager) ?? securityAsm.GetType(cryptographicInfo.CryptoManager) ?? coreAsm.GetType(cryptographicInfo.CryptoManager)); #if DEBUG long offset = watch.ElapsedMilliseconds; #endif byte[] key = keyDevice.GetBytes(KeySize / 8); #if DEBUG Console.WriteLine(Encryption_App.Resources.MainWindow_EncryptDataWithHeader_Actual_key_derivation_time__ + (watch.ElapsedMilliseconds - offset)); Console.WriteLine(Encryption_App.Resources.MainWindow_EncryptDataWithHeader_Expected_key_derivation_time__ + DesiredKeyDerivationMilliseconds); #endif // Create a handle to the key to allow control of it GCHandle keyHandle = GCHandle.Alloc(key, GCHandleType.Pinned); #if DEBUG Console.WriteLine(Encryption_App.Resources.MainWindow_EncryptDataWithHeader_Pre_encryption_time__ + watch.ElapsedMilliseconds); #endif // Encrypt the data to a temporary file encryptor.EncryptFileBytes(filePath, _dataTempFile, key, cryptographicInfo.EncryptionModeInfo.InitializationVector); #if DEBUG Console.WriteLine(Encryption_App.Resources.MainWindow_EncryptDataWithHeader_Post_encryption_time__ + watch.ElapsedMilliseconds); #endif if (cryptographicInfo.Hmac != null) { // Create the signature derived from the encrypted data and key byte[] signature = MessageAuthenticator.CreateHmac(_dataTempFile, key, hmacAlg); // Set the signature correctly in the CryptographicInfo object cryptographicInfo.Hmac.root_Hash = signature; } // Delete the key from memory for security ZeroMemory(keyHandle.AddrOfPinnedObject(), key.Length); keyHandle.Free(); StepEncryptStrings(); #if DEBUG Console.WriteLine(Encryption_App.Resources.MainWindow_EncryptDataWithHeader_Post_authenticate_time__ + watch.ElapsedMilliseconds); #endif // Write the CryptographicInfo object to a file cryptographicInfo.WriteHeaderToFile(filePath); #if DEBUG // We have to use Dispatcher.Invoke as the current thread can't access these objects this.dispatcher.Invoke(() => { EncryptOutput.Content = "Transferring the data to the file"; }); Console.WriteLine(Encryption_App.Resources.MainWindow_EncryptDataWithHeader_Post_header_time___0_, watch.ElapsedMilliseconds); #endif FileStatics.AppendToFile(filePath, _dataTempFile); #if DEBUG Console.WriteLine(Encryption_App.Resources.MainWindow_EncryptDataWithHeader_File_write_time__ + watch.ElapsedMilliseconds); #endif StepEncryptStrings(); GC.Collect(); }