質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

暗号化

ネットワークを通じてデジタルデータをやり取りする際に、第三者に解読されることのないよう、アルゴリズムを用いてデータを変換すること。

Q&A

解決済

1回答

6535閲覧

C#でAES暗号の復号する際のストリームについて

porepore

総合スコア15

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

暗号化

ネットワークを通じてデジタルデータをやり取りする際に、第三者に解読されることのないよう、アルゴリズムを用いてデータを変換すること。

0グッド

0クリップ

投稿2016/08/26 11:50

編集2016/08/26 13:28

お世話になります。
現在C#でファイルをAES暗号で暗号化しファイル出力、
復号の際は暗号化ファイルを読み込み復号しファイル出力するソースコードを書いています。
復号の際には暗号化ファイルを読み込み、標準出力したいと思っていますがうまくいかないため、
どのようにすれば良いか教えていただきたいです。
自分としてはコメントの①のFileStream outsをほかのストリームにすれば良いのではないかと考えています。
お忙しいと思いますが宜しくお願いします。

c#

1static void Main() 2 { 3 string sfile = @"C:\test\enc.txt"; //暗号化前ファイル 4 string dfile = @"C:\test\dec.txt"; //暗号化ファイル 5 string efile = @"C:\test\out.txt"; //復号ファイル 6 string key = @"hoge"; //パスワード 7 AesEnc(sfile, dfile, key); 8 AesDec(dfile, efile, key); 9 } 10//暗号化 11static void AesEnc(string sFile, string dFile, string key) 12 { 13 AesCryptoServiceProvider aes = new AesCryptoServiceProvider(); 14 15 aes.BlockSize = 128; 16 aes.KeySize = 128; 17 aes.Mode = CipherMode.CBC; 18 aes.Padding = PaddingMode.PKCS7; 19 20 aes.GenerateIV(); 21 byte[] byteIV = aes.IV; 22 23 byte[] bytesPassword = Encoding.UTF8.GetBytes(key); 24 byte[] bytesKey = new byte[16]; 25 26 for (int i = 0; i < 16; i++) 27 { 28 if (i < bytesPassword.Length) 29 { 30 bytesKey[i] = bytesPassword[i]; 31 } 32 else 33 { 34 bytesKey[i] = 0; } 35 } 36 37 aes.Key = bytesKey; 38 39 ICryptoTransform encrypt = aes.CreateEncryptor(); 40 FileStream outfs = new FileStream(dFile, FileMode.Create, FileAccess.Write); 41 outfs.Write(byteIV, 0, 16); 42 43 CryptoStream cs = new CryptoStream(outfs, encrypt, CryptoStreamMode.Write); 44 FileStream fs = new FileStream(sFile, FileMode.Open, FileAccess.Read); 45 46 byte[] buf = new byte[1024]; 47 int len; 48 49 while ((len = fs.Read(buf, 0, buf.Length)) > 0) 50 { 51 cs.Write(buf, 0, len); 52 53 } 54 fs.Close(); 55 cs.Close(); 56 encrypt.Dispose(); 57 outfs.Close(); 58 } 59 60//復号 61static void AesDec(string sFile, string dFile, string key) 62 { 63 AesCryptoServiceProvider aes = new AesCryptoServiceProvider(); 64 65 aes.BlockSize = 128; 66 aes.KeySize = 128; 67 aes.Mode = CipherMode.CBC; 68 aes.Padding = PaddingMode.PKCS7; 69 70 byte[] bytesPassword = Encoding.UTF8.GetBytes(key); 71 byte[] bytesKey = new byte[16]; 72 byte[] bytesIV = new byte[16]; 73 74 for (int i = 0; i < 16; i++) 75 { 76 if (i < bytesPassword.Length) 77 { 78 bytesKey[i] = bytesPassword[i]; 79 } 80 else 81 { 82 bytesKey[i] = 0; 83 } 84 } 85 86 aes.Key = bytesKey; 87 88 FileStream fs = new FileStream(sFile, FileMode.Open, FileAccess.Read); 89 90 fs.Read(bytesIV, 0, 16); 91 aes.IV = bytesIV; 92 93 ICryptoTransform encrypt = aes.CreateDecryptor(); 94 //① 95 FileStream outfs = new FileStream(dFile, FileMode.Create, FileAccess.Write); 96 CryptoStream cs = new CryptoStream(outfs, encrypt, CryptoStreamMode.Write); 97 98 byte[] buf = new byte[1024]; 99 100 int len; 101 102 while ((len = fs.Read(buf, 0, buf.Length)) > 0) 103 { 104 cs.Write(buf, 0, len); 105 Console.WriteLine(Encoding.GetEncoding("shift_jis").GetString(buf)); 106 } 107 108 fs.Close(); 109 cs.Close(); 110 encrypt.Dispose(); 111 outfs.Close(); 112 } 113 114

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

flied_onion

2016/08/26 13:18

どううまくいかないのですか?
flied_onion

2016/08/26 13:21

あと、暗号化の方のソースもあった方が、回答はしやすいです(暗号化ファイル作れないので確認しづらい)
porepore

2016/08/26 13:30

Console.WriteLine(outfs.ToString());としても表示されないことから ほかのストリームを使用すればできるのではないかと思っています。 (全く見当違いかもしれません・・・)
flied_onion

2016/08/26 13:46

追加ありがとうございます。 うーん、StringWriterなどにする手はありますが、気になるのは、バッファの境界に漢字の真ん中が来た場合ですかね。
porepore

2016/08/26 13:49

実際の運用で使う場合はファイル容量が1kb以下になると想定しています。 バッファも適当に決めているのでもう少し増やしても問題ないかと思います。
guest

回答1

0

ベストアンサー

一番簡単なのはMemoryStreamを使う事ですが、下の実装だとすべて読み終わってから出力することになります。
小さいサイズないいですが、巨大なファイルには向きません。

// AesDecの途中から ICryptoTransform encrypt = aes.CreateDecryptor(); // FileStream outfs = new FileStream(dFile, FileMode.Create, FileAccess.Write); using (var ms = new MemoryStream()) { CryptoStream cs = new CryptoStream(ms, encrypt, CryptoStreamMode.Write); byte[] buf = new byte[1024]; int len; while ((len = fs.Read(buf, 0, buf.Length)) > 0) { cs.Write(buf, 0, len); // Console.WriteLine(Encoding.GetEncoding("shift_jis").GetString(buf)); } fs.Close(); cs.Close(); encrypt.Dispose(); Console.WriteLine(Encoding.GetEncoding("shift_jis").GetString(ms.ToArray())); } // outfs.Close(); }

ループの途中で出力する手もありますが、出力していいタイミングかの判定が難しいかもしれませんね。
とりあえず、MemoryStreamの例を載せておきます。

なお、bufは暗号化されたデータなので(bufをcsに書き込むことで、csに設定されたstreamが復号されたバイトデータを得る)、bufを使ってもデータは得られません。
あと、途中までの読み取りで、WriteLineしてしまうと元々のデータに無いタイミングで改行してしまうので、Whileの中で逐次出力したい場合はWriteにしましょう。

投稿2016/08/26 14:03

flied_onion

総合スコア2604

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

porepore

2016/08/26 14:37

ありがとうございます。 この方法でうまくいきました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問