前提・実現したいこと
お世話になります。
aes暗号化した際に出力されるファイル名をdialog.FileNameで取得した文字列で決定したいと考えています。
aes暗号化はできているため、作成ファイルの文字列を自由に設定できるようにする部分をご教授いただけますと幸いです。
試したこと
aes暗号化した際の出力ファイル設定を下記のように試しております。
- 出力パスを"C:/Users/Documents/test.aes"に設定
→問題なくtestのaesファイルが作成される(ファイル名が可変ではないため要修正)
2 . 出力パスを System.IO.Path.GetFileName
で入力された文字列を読み取り、var aesName = filename.Replace("zip", "aes");
で拡張子をaesに変更
→暗号化ファイルが作成されない
文字列自体は1と同じだと思うので、ファイルが作成されない理由が分かりません。
該当コード
C#
1//AES暗号化 2 private void AesSaveAsButton_Click(object sender, RoutedEventArgs e) 3 { 4 var dialog = new SaveFileDialog(); 5 dialog.Filter = "zip|*.zip"; 6 if (dialog.ShowDialog() == true) 7 { 8 var filename = System.IO.Path.GetFileName(dialog.FileName); 9 10 var entryName = filename.Replace("zip", "json"); 11 //var aesName = filename.Replace("zip", "aes"); //作成されないため一旦コメントアウト 12 13 var json = JsonConvert.SerializeObject(_data, Formatting.Indented); 14 // JSON 文字列からエンコーディング UTF-8 でバイト列を作成 15 var bytes = Encoding.UTF8.GetBytes(json); 16 using (var ms = new MemoryStream()) 17 { 18 // メモリストリーム上にZipArchiveを作成する 19 using (var zipArchive = new ZipArchive(ms, ZipArchiveMode.Create, true)) 20 { 21 var entry = zipArchive.CreateEntry(entryName); 22 using (var es = entry.Open()) 23 { 24 // エントリにバイナリを書き込む 25 es.Write(bytes, 0, bytes.Length); 26 } 27 } 28 // MemoryStream からバイト列を取得してファイルを作成 29 byte[] zipBytes = ms.ToArray(); 30 File.WriteAllBytes(dialog.FileName, zipBytes); 31 Encode(dialog.FileName, "C:/Users/ユーザ名/Documents/test.aes"); 32 //Encode(dialog.FileName, aesName); //出力されない 33 } 34 } 35 } 36 //AES複合化 37 private void AesOpenAsButton_Click(object sender, RoutedEventArgs e) 38 { 39 var dialog = new OpenFileDialog(); 40 if (dialog.ShowDialog().Value) 41 { 42 Decode(dialog.FileName, "C:/Users/ユーザ名/Documents/test.aes");//←こちらも可変にする予定 43 var file = dialog.FileName; 44 try 45 { 46 var reader = new StreamReader(file); 47 var json = File.ReadAllText(dialog.FileName); 48 reader.Close(); 49 _data = JsonConvert.DeserializeObject<ObservableCollection<ManagementUnitData>>(json); 50 } 51 catch (Exception error) 52 { 53 if (error.Message != null) 54 Debug.WriteLine(error.Message); 55 } 56 if (_data != null) 57 { 58 DataContext = _data; 59 } 60 } 61 } 62 //aes暗号化 63 /// <summary> 64 /// 共有キー 65 /// </summary> 66 private const string AES_KEY = "-SENJU MURAMASA-"; 67 /// <summary> 68 /// バッファサイズ 69 /// </summary> 70 private const int BUFFER_SIZE = 1024 * 4; 71 /// <summary> 72 /// 共有キービットサイズ 73 /// </summary> 74 private const int KEY_SIZE = 128; 75 /// <summary> 76 /// 暗号操作のビットサイズ 77 /// </summary> 78 private const int BLOCK_SIZE = 128; 79 /// <summary> 80 /// 暗号化 81 /// </summary> 82 /// <param name="src">入力ファイルパス</param> 83 /// <param name="dst">出力ファイルパス</param> 84 static public void Encode(string src, string dst) 85 { 86 //aes暗号化 87 using (AesManaged aes = new AesManaged()) 88 { 89 //AESインスタンスのパラメータ設定 90 aes.KeySize = KEY_SIZE; 91 aes.BlockSize = BLOCK_SIZE; 92 aes.Mode = CipherMode.CBC; 93 aes.Key = Encoding.UTF8.GetBytes(AES_KEY); 94 //初期ベクターの生成 95 aes.GenerateIV(); 96 //暗号化オブジェクトの生成 97 ICryptoTransform ct = aes.CreateEncryptor(aes.Key, aes.IV); 98 //出力ファイルストリーム 99 using (FileStream outFs = new FileStream(dst, FileMode.Create, FileAccess.Write)) 100 { 101 //初期ベクター書き込み 102 outFs.Write(aes.IV, 0, aes.IV.Length); 103 //暗号変換のストリーム(暗号化) 104 using (CryptoStream cs = new CryptoStream(outFs, ct , CryptoStreamMode.Write)) 105 { 106 //Deflateアルゴリズムを使用したストリーム(圧縮) 107 using (DeflateStream ds = new DeflateStream(cs, CompressionMode.Compress)) 108 { 109 //入力ファイルストリーム 110 using (FileStream inFs = new FileStream(src, FileMode.Open, FileAccess.Read)) 111 { 112 byte[] buf = new byte[BUFFER_SIZE]; 113 for(int size = inFs.Read(buf, 0, buf.Length); size>0; size = inFs.Read(buf, 0, buf.Length)) 114 { 115 //出力ファイルへの書き込み 116 ds.Write(buf, 0, size); 117 } 118 } 119 } 120 } 121 } 122 } 123 } 124 /// <summary> 125 /// 複合化 126 /// </summary> 127 /// <param name="src">入力ファイルパス</param> 128 /// <param name="dst">出力ファイルパス</param> 129 static public void Decode(string src, string dst) 130 { 131 // 高度暗号化標準(AES) 132 using (AesManaged aes = new AesManaged()) 133 { 134 // AESインスタンスのパラメータ設定 135 aes.KeySize = KEY_SIZE; 136 aes.BlockSize = BLOCK_SIZE; 137 aes.Mode = CipherMode.CBC; 138 aes.Key = Encoding.UTF8.GetBytes(AES_KEY); 139 // 入力ファイルストリーム 140 using (FileStream inFs = new FileStream(src, FileMode.Open, FileAccess.Read)) 141 { 142 // 初期化ベクター(IV)読込 143 byte[] iv = new byte[aes.IV.Length]; 144 inFs.Read(iv, 0, iv.Length); 145 aes.IV = iv; 146 // 複合化オブジェクト生成 147 ICryptoTransform ct = aes.CreateDecryptor(aes.Key, aes.IV); 148 // 暗号変換のストリーム(複合化) 149 using (CryptoStream cs = new CryptoStream(inFs, ct, CryptoStreamMode.Read)) 150 { 151 // Deflateアルゴリズムを使用したストリーム(圧縮解除) 152 using (DeflateStream ds = new DeflateStream(cs, CompressionMode.Decompress)) 153 { 154 // 出力ファイルストリーム 155 using (FileStream outFs = new FileStream(dst, FileMode.Create, FileAccess.Write)) 156 { 157 // 複合化した結果を書き込む 158 byte[] buf = new byte[BUFFER_SIZE]; 159 for (int size = ds.Read(buf, 0, buf.Length); size > 0; size = ds.Read(buf, 0, buf.Length)) 160 { 161 outFs.Write(buf, 0, size); 162 } 163 } 164 } 165 } 166 } 167 } 168 }
> "C:/Users/Documents/test.aes"
エスケープしてませんが、これで
> →問題なくtestのaesファイルが作成される(ファイル名が可変ではないため要修正)
なのでしょうか?
まあ本題はディレクトリ名部分をなぜか削除しているところだと思いますが。
提示のコードが
> var entryName = filename.Replace("zip", "json");
> //var aesName = filename.Replace("zip", "aes"); //作成されないため一旦コメントアウト
...
> var entry = zipArchive.CreateEntry(entryName);
...
> Encode(dialog.FileName, "C:/Users/Documents/test.aes");
> //Encode(dialog.FileName, aesName); //出力されない
などとなっていて、ところどころ利用している変数名が合致していないような気がします。
確認用に変更しているだけかもしれませんが、実はそこを間違っていた、なんてことはないですか。
> まあ本題はディレクトリ名部分をなぜか削除しているところだと思いますが。
仰る通り、ディレクトリを一部消去しておりました。(コード上では入っています。)
下記を編集し追加させていただきます。
"C:/Users/ユーザ名/Documents/test.aes"
そうではなく、System.IO.Path.GetFileName を使ってディレクトリ名を削除しているという意味です。
filename は結局このコードでは捨てられていますが、おそらく本番では使われているんでしょう?
よく読んでいませんでした。entryname として zip に登録するのに使われているのでディレクトリ名は要りませんね。
>Zuishinさん
アドバイスいただきありがとうございます。
System.IO.Path.GetFileNameの仕様を勘違いしておりました。
ディレクトリ名を削除しないGetDirectoryName()メソッドを使用するべきでした。
ちょっと補足です。
回答者さんのソースで拡張子を変更したいことは分かるのですが、単純な置換を使用すると"zip"という文字が含まれるファイル名(例えばZipper.zip)を選択された場合に誤った変換になると思います。
拡張子の変換メソッドが用意されてますのでそちらを使用する方がいいと思います。
https://dobon.net/vb/dotnet/file/changeextension.html
>dekaakiさん
そうですね、汎用的な形にするのであればこちらの方が有効ですね。
補足ありがとうございます!
回答2件
あなたの回答
tips
プレビュー