こんにちは。初心者プログラマです。
どうしても自分で解決できなかったので、質問させてください。
概要
外部にある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}
いろいろ自分で検索して試しましたが、何かの見落としがあるようで、エラーを取ることができず、お力を貸していただきたく、書き込ませていただきました。
もし、これ以外に、解決のため必要な情報がありましたら、ご指摘いただければ追記いたします。
どうか、よろしくお願いいたします。
回答1件
あなたの回答
tips
プレビュー