public async Task <FileSystemStorageFile> EncryptAsync(string OutputDirectory, string Key, int KeySize, CancellationToken CancelToken = default) { if (string.IsNullOrWhiteSpace(OutputDirectory)) { throw new ArgumentNullException(nameof(OutputDirectory), "Argument could not be null"); } if (KeySize != 256 && KeySize != 128) { throw new InvalidEnumArgumentException("AES密钥长度仅支持128或256任意一种"); } if (string.IsNullOrEmpty(Key)) { throw new ArgumentNullException(nameof(Key), "Parameter could not be null or empty"); } int KeyLengthNeed = KeySize / 8; byte[] KeyArray = Key.Length > KeyLengthNeed ? Encoding.UTF8.GetBytes(Key.Substring(0, KeyLengthNeed)) : Encoding.UTF8.GetBytes(Key.PadRight(KeyLengthNeed, '0')); string EncryptedFilePath = System.IO.Path.Combine(OutputDirectory, $"{System.IO.Path.GetFileNameWithoutExtension(Name)}.sle"); if (await CreateAsync(EncryptedFilePath, StorageItemTypes.File, CreateOption.GenerateUniqueName).ConfigureAwait(true) is FileSystemStorageFile EncryptedFile) { using (FileStream EncryptFileStream = await EncryptedFile.GetFileStreamFromFileAsync(AccessMode.Write).ConfigureAwait(true)) { string IV = SecureAccessProvider.GetFileEncryptionAesIV(Package.Current); using (AesCryptoServiceProvider AES = new AesCryptoServiceProvider { KeySize = KeySize, Key = KeyArray, Mode = CipherMode.CBC, Padding = PaddingMode.Zeros, IV = Encoding.UTF8.GetBytes(IV) }) { using (FileStream OriginFileStream = await GetFileStreamFromFileAsync(AccessMode.Read).ConfigureAwait(true)) using (ICryptoTransform Encryptor = AES.CreateEncryptor()) { byte[] ExtraInfoPart1 = Encoding.UTF8.GetBytes($"${KeySize}|{System.IO.Path.GetExtension(Path)}$"); await EncryptFileStream.WriteAsync(ExtraInfoPart1, 0, ExtraInfoPart1.Length, CancelToken).ConfigureAwait(true); byte[] PasswordConfirm = Encoding.UTF8.GetBytes("PASSWORD_CORRECT"); byte[] PasswordConfirmEncrypted = Encryptor.TransformFinalBlock(PasswordConfirm, 0, PasswordConfirm.Length); await EncryptFileStream.WriteAsync(PasswordConfirmEncrypted, 0, PasswordConfirmEncrypted.Length, CancelToken).ConfigureAwait(true); using (CryptoStream TransformStream = new CryptoStream(EncryptFileStream, Encryptor, CryptoStreamMode.Write)) { await OriginFileStream.CopyToAsync(TransformStream, 2048, CancelToken).ConfigureAwait(true); } } } } await EncryptedFile.RefreshAsync().ConfigureAwait(true); return(EncryptedFile); } else { return(null); } }
private async Task ImportFilesAsync(IEnumerable <StorageFile> FileList) { if (FileList.Any()) { await ActivateLoading(true, DisplayString : Globalization.GetString("Progress_Tip_Importing")); Cancellation = new CancellationTokenSource(); try { ulong TotalSize = 0; ulong CurrentPosition = 0; List <FileSystemStorageFile> NewFileList = new List <FileSystemStorageFile>(); foreach (StorageFile ImportFile in FileList) { FileSystemStorageFile File = await FileSystemStorageItemBase.CreatedByStorageItemAsync(ImportFile); if (File != null) { NewFileList.Add(File); TotalSize += File.SizeRaw; } } foreach (FileSystemStorageFile OriginFile in NewFileList) { string EncryptedFilePath = Path.Combine(SecureFolder.Path, $"{Path.GetFileNameWithoutExtension(OriginFile.Name)}.sle"); if (await FileSystemStorageItemBase.CreateAsync(EncryptedFilePath, StorageItemTypes.File, CreateOption.GenerateUniqueName) is FileSystemStorageFile EncryptedFile) { using (FileStream OriginFStream = await OriginFile.GetFileStreamFromFileAsync(AccessMode.Read)) using (FileStream EncryptFStream = await EncryptedFile.GetFileStreamFromFileAsync(AccessMode.Write)) using (SLEOutputStream SLEStream = new SLEOutputStream(EncryptFStream, OriginFile.Name, AESKey, AESKeySize)) { await OriginFStream.CopyToAsync(SLEStream, OriginFStream.Length, async (s, e) => { await Dispatcher.RunAsync(CoreDispatcherPriority.Low, () => { ProBar.IsIndeterminate = false; ProBar.Value = Convert.ToInt32((CurrentPosition + Convert.ToUInt64(e.ProgressPercentage / 100d * OriginFile.SizeRaw)) * 100d / TotalSize); }); }, Cancellation.Token); CurrentPosition += OriginFile.SizeRaw; await Dispatcher.RunAsync(CoreDispatcherPriority.Low, () => { ProBar.Value = Convert.ToInt32(CurrentPosition * 100d / TotalSize); }); } await EncryptedFile.RefreshAsync(); SecureCollection.Add(EncryptedFile); await OriginFile.DeleteAsync(false); } } } catch (OperationCanceledException cancelException) { LogTracer.Log(cancelException, "Import items to SecureArea have been cancelled"); } catch (Exception ex) { LogTracer.Log(ex, "An exception was threw when importing file"); QueueContentDialog Dialog = new QueueContentDialog { Title = Globalization.GetString("Common_Dialog_ErrorTitle"), Content = Globalization.GetString("QueueDialog_EncryptError_Content"), CloseButtonText = Globalization.GetString("Common_Dialog_CloseButton") }; _ = await Dialog.ShowAsync(); } finally { Cancellation.Dispose(); Cancellation = null; await ActivateLoading(false); } } }