🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

暗号化

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

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

5108閲覧

暗号化後のファイルをゲーム内で復号しようとしたらエラーになりました

BinaryNumber

総合スコア13

C#

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

暗号化

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

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2019/09/25 04:55

編集2019/09/25 07:27

こんにちは。初心者プログラマです。
どうしても自分で解決できなかったので、質問させてください。

概要

外部にあるcsvファイルを暗号化し、Resources下に置いています。
そして、Unity上で復号化しようとすると、エラーになってしまいます。

詳細

外部にあるcsvファイル(UTF8)を暗号化して、UnityのAssets/Resourcesの中に置きます。
ファイルで書き出すときに、書き出す内容を復号化関数で確認すると、問題なく復号化されます。
Unityで作成しているゲーム内で、最初のSceneでResources下のファイルを読み込みます。ところが、この、読み込むとき、書き出すときに使用した関数とまったく同じコードを使っているのに、エラーが出てしまい、復号ができません。
読み込みが失敗しているのかと内容を確認しましたが、読み込みはできているようでした(以下のコード内の encrypted を確認したらちゃんと読めているようです)。

エラー内容

CryptographicException: Length of the data to decrypt is invalid.

System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock (System.Byte[] inputBuffer, System.Int32 inputOffset, System.Int32 inputCount) (at <a8ed250850854b439cedc18931a314fe>:0)
.Decode () (at Assets/Scripts/.cs:146)
.Init () (at Assets/Scripts/.cs:54)

環境

Unity : 2019.2.0f1 Personal
ただし、2018.2.6f1で作成していたものを移動させた形です(そのためか[PREVIEW PACKAGES IN USE]と表示されています)。
Visual Studio : 2019 Version 16.0.2
これもまた、以前はVisual Studio2017を使っていたので、影響している可能性はあります。

コード

暗号化部分

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using System.Text; 5using System.IO; 6using System; 7using System.Security.Cryptography; 8 9public class * : MonoBehaviour { 10 11 private string guitxt = ""; 12 private byte[] encrypted; 13 private string plain = ""; 14 15 16 // Use this for initialization 17 void Start () { 18 string filename1 = Application.dataPath + "/../../test.csv"; 19 20 if (File.Exists(filename1)) 21 { 22 ReadFile(filename1); 23 24 string filename2 = Application.dataPath + "/Resources/test.csv"; 25 26 if (File.Exists(filename2)) 27 { 28 Encrypt(); 29 File.WriteAllBytes(filename2, encrypted); 30 Debug.Log("暗号:" + encrypted); 31 32 Decode(); 33 Debug.Log("復号:" + plain); 34 } 35 } 36 } 37 38 void ReadFile(string filename) 39 { 40 FileInfo fi = new FileInfo(filename); 41 42 try 43 { 44 // 一行毎読み込み 45 using (StreamReader sr = new StreamReader(fi.OpenRead(), Encoding.UTF8)) 46 { 47 guitxt = sr.ReadToEnd(); 48 } 49 } 50 catch (Exception e) 51 { 52 // 改行コード 53 guitxt += SetDefaultText(); 54 } 55 56 } 57 58 // 改行コード処理 59 string SetDefaultText() 60 { 61 return "C#あ\n"; 62 } 63 64 // 暗号化処理 65 void Encrypt() 66 { 67 RijndaelManaged rijndael = new RijndaelManaged(); 68 rijndael.KeySize = 128; 69 rijndael.BlockSize = 128; 70 71 // pw, vectorの内容はダミーで、実際には英数字で構成されています 72 string pw = "abcdefghijklmnop"; 73 string vector = "0123456789012345"; 74 75 byte[] bSalt = Encoding.UTF8.GetBytes(vector); 76 Rfc2898DeriveBytes deriveBytes = new Rfc2898DeriveBytes(pw, bSalt); 77 deriveBytes.IterationCount = 1000; // 反復回数 78 79 rijndael.Key = deriveBytes.GetBytes(rijndael.KeySize / 8); 80 rijndael.IV = deriveBytes.GetBytes(rijndael.BlockSize / 8); 81 82 // 暗号化 83 ICryptoTransform encryptor = rijndael.CreateEncryptor(); 84 byte[] src = Encoding.UTF8.GetBytes(guitxt); 85 encrypted = encryptor.TransformFinalBlock(src, 0, src.Length); 86 87 encryptor.Dispose(); 88 } 89 90 void Decode() 91 { 92 RijndaelManaged rijndael = new RijndaelManaged(); 93 rijndael.KeySize = 128; 94 rijndael.BlockSize = 128; 95 96 // パスワードから共有キーと初期化ベクターを作成 97 string pw = "abcdefghijklmnop"; 98 string vector = "0123456789012345"; 99 100 byte[] bSalt = Encoding.UTF8.GetBytes(vector); 101 Rfc2898DeriveBytes deriveBytes = new Rfc2898DeriveBytes(pw, bSalt); 102 deriveBytes.IterationCount = 1000; // 反復回数 103 104 rijndael.Key = deriveBytes.GetBytes(rijndael.KeySize / 8); 105 rijndael.IV = deriveBytes.GetBytes(rijndael.BlockSize / 8); 106 107 // 復号化 108 ICryptoTransform decryptor = rijndael.CreateDecryptor(); 109 byte[] src = decryptor.TransformFinalBlock(encrypted, 0, encrypted.Length); 110 111 Debug.Log("復号化: " + src); 112 113 plain = Encoding.UTF8.GetString(src); 114 115 decryptor.Dispose(); 116 117 } 118}

復号化部分

C#

1using System.Collections; 2using System.Collections.Generic; 3using System.IO; 4using System.Linq; 5using System.Security.Cryptography; 6using System.Text; 7using UnityEngine; 8 9public class * : MonoBehaviour 10{ 11 private static byte[] encrypted; 12 private static string plain = ""; 13 14 // ファイル名 15 private const string FILENAME = "test"; 16 17 // 問題文のcsvファイル 18 private static TextAsset csvFile; 19 20 [RuntimeInitializeOnLoadMethod()] 21 static void Init() 22 { 23 #if UNITY_EDITOR 24 if (UnityEditor.EditorApplication.isPlayingOrWillChangePlaymode == false) { return; } 25 #endif 26 27 // ファイルを読み込む 28 csvFile = Resources.Load(FILENAME) as TextAsset; 29 30 // 復号化 31 encrypted = csvFile.bytes; 32 Decode(); 33 34 // 以後の処理 35 // (省略) 36 } 37 38 39static void Decode() 40 { 41 RijndaelManaged rijndael = new RijndaelManaged(); 42 rijndael.KeySize = 128; 43 rijndael.BlockSize = 128; 44 45 // パスワードから共有キーと初期化ベクターを作成 46 string pw = "abcdefghijklmnop"; 47 string vector = "0123456789012345"; 48 49 byte[] bSalt = Encoding.UTF8.GetBytes(vector); 50 Rfc2898DeriveBytes deriveBytes = new Rfc2898DeriveBytes(pw, bSalt); 51 deriveBytes.IterationCount = 1000; // 反復回数 52 53 rijndael.Key = deriveBytes.GetBytes(rijndael.KeySize / 8); 54 rijndael.IV = deriveBytes.GetBytes(rijndael.BlockSize / 8); 55 56 // 復号化 57 ICryptoTransform decryptor = rijndael.CreateDecryptor(); 58 byte[] src = decryptor.TransformFinalBlock(encrypted, 0, encrypted.Length); 59 plain = Encoding.UTF8.GetString(src); 60 61 decryptor.Dispose(); 62}

いろいろ自分で検索して試しましたが、何かの見落としがあるようで、エラーを取ることができず、お力を貸していただきたく、書き込ませていただきました。
もし、これ以外に、解決のため必要な情報がありましたら、ご指摘いただければ追記いたします。
どうか、よろしくお願いいたします。

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

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

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

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

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

Zuishin

2019/09/25 06:53

暗号化部分、書き出し部分、読み込み部分が必要です。
BinaryNumber

2019/09/25 07:29

ご指摘ありがとうございます。 暗号化部分のコードと、復号化の際の読み込み部分を追加してみました。 まだ不足がありましたら、お手数ですが、またご指摘いただけると助かります。
guest

回答1

0

ベストアンサー

テキストアセット

.txt と .bytes 拡張子によるファイルは、それぞれ、テキストとバイナリファイルとして扱われるので注意してください。これらのファイルからデータを読み込もうとするとき、予想外の動作をしてしまうかもしれないのでバイナリファイルを .txt 拡張子で保存しないでください。

FILENAME を test.bytes にしてみてください。

投稿2019/09/25 07:35

Zuishin

総合スコア28669

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

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

BinaryNumber

2019/09/25 07:45

早速のお返事、ありがとうございます。 > FILENAME を test.bytes にしてみてください。 とのことですが、 1. FILENAMEの定義を"test"→"test.bytes"にする 2. Resourceのファイル名を"test.csv"→"test.bytes"にする のいずれかでしょうか、それとも別のことをすればよいのでしょうか。 理解が足りなくて申し訳ありませんが、教えていただけると助かります。 よろしくお願いします。
Zuishin

2019/09/25 07:46

リンク先を一通り読んでみてください。今後も無駄にならないはずです。
BinaryNumber

2019/09/25 08:06

大変失礼いたしました。参照リンクだと思っておりませんでした。完全に勘違いしておりました、申し訳ございません。 ファイルをtest.csvからtest.bytes、出力先もtest.csvからtest.bytesに変更することで、今回の読み出しに成功しました。 ご指摘いただき助かりました。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問