本日は hololens の技術調査枠です。
アプリの情報を暗号化して書き出し、復号化して読み込みます。
前提条件
以下の前回記事の続きになります。
bluebirdofoz.hatenablog.com
bluebirdofoz.hatenablog.com
暗号化と復号化
今回は以下のページを参考に暗号化と復号化を実施してみました。
docs.microsoft.com
docs.microsoft.com
前回記事のクラスに暗号化して情報を書き出す関数と、復号化を行って情報を読み込む関数を追加します。
・DataSaveManager.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; namespace TestUtilities { /// <summary> /// データファイル構造クラス /// </summary> [System.Serializable] public class XmlSaveData { /// <summary> /// 保存時刻 /// </summary> public System.DateTime SaveDataTime; /// <summary> /// 状態名 /// </summary> public string Name; /// <summary> /// 経過日数 /// </summary> public int Days; } public class DataSaveManager : MonoBehaviour { // Encryption key used to encrypt the stream. // The same value must be used to encrypt and decrypt the stream. // ストリームの暗号化に使用される暗号化キー。 // ストリームの暗号化と復号化には同じ値を使用する必要があります。 byte[] key = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 }; /// <summary> /// データファイル名(XML)のベース /// </summary> private string p_DataFileName = "SaveData.xml"; /// <summary> /// データファイル名(暗号化XML)のベース /// </summary> private string p_DataFileNameCryptography = "SaveData.bin"; /// <summary> /// データファイル情報 /// </summary> [SerializeField, Tooltip("データファイル情報")] private XmlSaveData p_SaveData = new XmlSaveData(); /// <summary> /// データファイルディレクトリパス /// 実行環境によって参照ディレクトリを変更する /// </summary> private string SettingFileDirectoryPath() { string directorypath = ""; #if WINDOWS_UWP // HoloLens上での動作の場合、LocalAppData/AppName/LocalStateフォルダを参照する directorypath = Windows.Storage.ApplicationData.Current.LocalFolder.Path; #elif UNITY_IOS // iOS上での動作の場合、/var/mobile/Applications/アプリ番号/Documentsフォルダを参照する directorypath = UnityEngine.Application.persistentDataPath; #else // Unity上での動作の場合、Assets/StreamingAssetsフォルダを参照する directorypath = UnityEngine.Application.streamingAssetsPath; #endif return directorypath; } /// <summary> /// データファイルファイルパス(XML) /// 実行環境によって参照ディレクトリを変更する /// </summary> private string XMLFilePath() { string filepath = ""; filepath = System.IO.Path.Combine(SettingFileDirectoryPath(), p_DataFileName); return filepath; } /// <summary> /// データファイルファイルパス(暗号化XML) /// 実行環境によって参照ディレクトリを変更する /// </summary> private string XMLFilePathCryptography() { string filepath = ""; filepath = System.IO.Path.Combine(SettingFileDirectoryPath(), p_DataFileNameCryptography); return filepath; } /// <summary> /// データファイル読み込み(XML) /// </summary> public bool XMLRead() { // 読み込み成否 bool ret = false; // オブジェクトの型を指定して Serializer オブジェクトを作成する System.Xml.Serialization.XmlSerializer serializer; serializer = new System.Xml.Serialization.XmlSerializer(typeof(XmlSaveData)); // ファイルの存在確認 if (System.IO.File.Exists(XMLFilePathCryptography()) == true) { // 読み込みファイルを開く System.IO.StreamReader streamreader; #if WINDOWS_UWP // 読み込みファイルを開く(UWPアプリではStreamReader(filepath)メソッドは使用不可) streamreader = new System.IO.StreamReader((System.IO.Stream)System.IO.File.OpenRead(XMLFilePath())); #else // 読み込みファイルを開く streamreader = new System.IO.StreamReader(XMLFilePath(), new System.Text.UTF8Encoding(false)); #endif // XMLファイルから逆シリアル化する p_SaveData = (XmlSaveData)serializer.Deserialize(streamreader); #if WINDOWS_UWP // ファイルを閉じる(UWPアプリではClose()メソッドは使用不可) streamreader.Dispose(); #else // ファイルを閉じる streamreader.Close(); #endif // 読み込み成功 ret = true; } return ret; } /// <summary> /// データファイル読み込み(暗号化XML) /// (データが短いと読み込みに失敗するので注意) /// </summary> public bool XMLReadCryptography() { // 読み込み成否 bool ret = false; // オブジェクトの型を指定して Serializer オブジェクトを作成する System.Xml.Serialization.XmlSerializer serializer; serializer = new System.Xml.Serialization.XmlSerializer(typeof(XmlSaveData)); // ファイルの存在確認 if (System.IO.File.Exists(XMLFilePathCryptography()) == true) { // ファイルストリームを作成する。 using (System.IO.FileStream myStream = new System.IO.FileStream(XMLFilePathCryptography(), System.IO.FileMode.Open)) { // デフォルトのAes実装クラスの新しいインスタンスを作成します。 using (System.Security.Cryptography.Aes aes = System.Security.Cryptography.Aes.Create()) { // ファイルの先頭からIV値を読み取ります。 byte[] iv = new byte[aes.IV.Length]; myStream.Read(iv, 0, iv.Length); // CryptoStreamを作成し、ファイルストリームを渡し、キーとIVを使用してAesクラスで復号化します。 using (System.Security.Cryptography.CryptoStream cryptStream = new System.Security.Cryptography.CryptoStream( myStream, aes.CreateDecryptor(key, iv), System.Security.Cryptography.CryptoStreamMode.Read)) { // 読み込みファイルを開く using (System.IO.StreamReader streamreader = new System.IO.StreamReader(cryptStream)) { // XMLファイルから逆シリアル化する p_SaveData = (XmlSaveData)serializer.Deserialize(streamreader); #if WINDOWS_UWP // ファイルを閉じる(UWPアプリではClose()メソッドは使用不可) streamreader.Dispose(); #else // ファイルを閉じる streamreader.Close(); #endif } } } } // 読み込み成功 ret = true; } return ret; } /// <summary> /// データファイル書き込み(XML) /// </summary> public bool XMLWrite() { // 書き込み成否 bool ret = false; // オブジェクトの型を指定して Serializer オブジェクトを作成する System.Xml.Serialization.XmlSerializer serializer; serializer = new System.Xml.Serialization.XmlSerializer(typeof(XmlSaveData)); // ディレクトリの存在確認 if (System.IO.Directory.Exists(SettingFileDirectoryPath()) == true) { // UWPの場合は書き込み前に既存のファイルを削除する #if WINDOWS_UWP // ファイルの存在確認 if (System.IO.File.Exists(XMLFilePath()) == true) { System.IO.File.Delete(XMLFilePath()); } #endif // 書き込みファイルを開く System.IO.StreamWriter streamwriter; #if WINDOWS_UWP // 書き込みファイルを開く(UWPアプリではStreamWriter(filepath)メソッドは使用不可) streamwriter = new System.IO.StreamWriter((System.IO.Stream)System.IO.File.OpenWrite(XMLFilePath())); #else // 書き込みファイルを開く streamwriter = new System.IO.StreamWriter(XMLFilePath(), false, new System.Text.UTF8Encoding(false)); #endif // シリアル化してXMLファイルに保存する serializer.Serialize(streamwriter, p_SaveData); #if WINDOWS_UWP // ファイルを閉じる(UWPアプリではClose()メソッドは使用不可) streamwriter.Dispose(); #else // ファイルを閉じる streamwriter.Close(); #endif // 書き込み成功 ret = true; } return ret; } /// <summary> /// データファイル書き込み(暗号化XML) /// (データが短いと読み込みに失敗するので注意) /// </summary> public bool XMLWriteCryptography() { // 書き込み成否 bool ret = false; // オブジェクトの型を指定して Serializer オブジェクトを作成する System.Xml.Serialization.XmlSerializer serializer; serializer = new System.Xml.Serialization.XmlSerializer(typeof(XmlSaveData)); // ディレクトリの存在確認 if (System.IO.Directory.Exists(SettingFileDirectoryPath()) == true) { // UWPの場合は書き込み前に既存のファイルを削除する #if WINDOWS_UWP // ファイルの存在確認 if (System.IO.File.Exists(XMLFilePathCryptography()) == true) { System.IO.File.Delete(XMLFilePathCryptography()); } #endif // ファイルストリームを作成する。 using (System.IO.FileStream myStream = new System.IO.FileStream(XMLFilePathCryptography(), System.IO.FileMode.OpenOrCreate)) { // デフォルトのAes実装クラスの新しいインスタンスを作成します。 using (System.Security.Cryptography.Aes aes = System.Security.Cryptography.Aes.Create()) { // 暗号化キーを構成します。 aes.Key = key; // ファイルの先頭にIVを格納します。 // この情報は復号化に使用されます。 byte[] iv = aes.IV; myStream.Write(iv, 0, iv.Length); // CryptoStreamを作成し、FileStreamを渡して、Aesクラスで暗号化します。 using (System.Security.Cryptography.CryptoStream cryptStream = new System.Security.Cryptography.CryptoStream( myStream, aes.CreateEncryptor(), System.Security.Cryptography.CryptoStreamMode.Write)) { // 書き込みファイルを開く using (System.IO.StreamWriter streamwriter = new System.IO.StreamWriter(cryptStream)) { // シリアル化してXMLファイルに保存する serializer.Serialize(streamwriter, p_SaveData); #if WINDOWS_UWP // ファイルを閉じる(UWPアプリではClose()メソッドは使用不可) streamwriter.Dispose(); #else // ファイルを閉じる streamwriter.Close(); #endif } } } } // 書き込み成功 ret = true; } return ret; } /// <summary> /// 初期化関数 /// </summary> void Awake() { // 処理無し } /// <summary> /// 設定取得関数 /// </summary> public XmlSaveData GetSaveData() { return p_SaveData; } } }
HoloLens2 にアプリを展開して Save/Load を行い、暗号化と復号化を介してデータの書き込みと読み込みができることを確認しました。