62
63

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Assetの暗号化について

Last updated at Posted at 2014-06-26

#はじめに#
Assetの暗号化について、自分なりに調べたものをまとめてみます。

#Assetを暗号化するには#
暗号化するAssetをTextAssetとして扱い、byte配列を操作(暗号化、及び復号化)することになります。

#AssetをTextAssetとして扱う#
詳しくは以下のドキュメントの下部、[バイナリ データ]以下に記載されています。

暗号化したいAssetの拡張子を[.bytes]に変更するだけでTextAssetとして読み込み、直接バイナリデータを扱うことができるようです。思ってたより簡単なことでした。

#TextAssetを暗号化#
C#ではAESによる暗号化ライブラリを使用する事が可能なので、そちらを使用する事にしました。

以下のサイトを参考にしました。

実は、こちらの記事に辿り着く前に、

こちらの記事を参考にしていたのですが、こちらの方法だとエラーが発生してしまい、頭を抱えた経緯がありました.....。
調べたところ、UnityAnswersでもトピックが立てられていました。

「.NET 2.0 subset」ではサポートされていないようです。

#やってみた#

AesCryptography
using UnityEngine;
using System;
using System.IO;
using System.Text;
using System.Collections;
using System.Security.Cryptography;


public class AesCryptography
{

    // 256bit(32byte)のInitVector(初期ベクタ)とKey(暗号キー)
    private const string AesInitVector  = @"hogehogehogehogehogehogehogehoge";
    private const string AesKey         = @"piyopiyopiyopiyopiyopiyopiyopiyo";

    private const int   BlockSize       = 256;
    private const int   KeySize         = 256;


    /// <summary>
    /// 暗号化スクリプト
    /// </summary>
    /// <returns>byte[] 暗号化したbyte列</returns>
    public byte[]  Encrypt( byte[] binData )
    {
        RijndaelManaged myRijndael  = new RijndaelManaged();
        myRijndael.Padding          = PaddingMode.Zeros;
        myRijndael.Mode             = CipherMode.CBC;
        myRijndael.KeySize          = KeySize;
        myRijndael.BlockSize        = BlockSize;

        byte[] key            = new byte[0];
        byte[] InitVector     = new byte[0];

        key         = System.Text.Encoding.UTF8.GetBytes( AesKey );
        InitVector  = System.Text.Encoding.UTF8.GetBytes( AesInitVector );

        ICryptoTransform encryptor = myRijndael.CreateEncryptor( key, InitVector );

        MemoryStream msEncrypt  = new MemoryStream();
        CryptoStream csEncrypt  = new CryptoStream( msEncrypt, encryptor, CryptoStreamMode.Write );

        byte[] src = binData;

        // 暗号化する
        csEncrypt.Write( src, 0, src.Length );
        csEncrypt.FlushFinalBlock();

        byte[] dest = msEncrypt.ToArray();

        return dest;
    }



    /// <summary>
    /// 複合化スクリプト
    /// </summary>
    /// <returns>byte[] 複合化したbyte列</returns>
    public byte[] Decrypt ( byte[] binData )
    {

        RijndaelManaged myRijndael  = new RijndaelManaged();
        myRijndael.Padding          = PaddingMode.Zeros;
        myRijndael.Mode             = CipherMode.CBC;
        myRijndael.KeySize          = KeySize;
        myRijndael.BlockSize        = BlockSize;

        byte[] key                  = new byte[0];
        byte[] InitVector           = new byte[0];

        key         = System.Text.Encoding.UTF8.GetBytes( AesKey );
        InitVector  = System.Text.Encoding.UTF8.GetBytes( AesInitVector );

        ICryptoTransform decryptor = myRijndael.CreateDecryptor( key, InitVector );
        byte[] src  = binData;
        byte[] dest = new byte[ src.Length ];

        MemoryStream msDecrypt = new MemoryStream( src );
        CryptoStream csDecrypt = new CryptoStream( msDecrypt, decryptor, CryptoStreamMode.Read );

        // 複号化する
        csDecrypt.Read( dest, 0, dest.Length );

        return dest;
    }


}

hogeとかpiyoと書いてある場所は任意に作成したものを使用して下さい。

#エディター上でできるようにした#
選択中のAssetを暗号化、及び復号化し、任意の場所に変換後のAssetを保存するエディタースクリプトを書きました。

AssetCryptography.cs

public class AssetCryptography
{

    private const string SaveExtension = ".bytes";

    /// <summary>
    /// 暗号化スクリプト
    /// </summary>
    [ MenuItem("Assets/Cryptography/Aes/Encrypt")]
    static void AssetEncrypt ()
    {
        //Assetをbytes拡張子で保存したものを取得
        TextAsset   obj     = (TextAsset)Selection.activeObject;
        AesCryptography aesCryptography = new AesCryptography();

        byte[]  encryptData = aesCryptography.Encrypt( obj.bytes );

        //保存するパスを選択
        string exportPath   = EditorUtility.OpenFolderPanel( "保存するフォルダを選択してください", Application.dataPath, "" );
        if( exportPath == null )
        {
            Debug.LogError( "選択時にエラーが発生しました" );
            return;
        }

        // 暗号化したファイルを保存
        File.WriteAllBytes( exportPath + "/" + obj.name + SaveExtension, encryptData );
    }


    /// <summary>
    /// 復号化スクリプト
    /// </summary>
    [ MenuItem("Assets/Cryptography/Aes/Decrypt")]
    static void AssetDecrypt ()
    {
        //Assetをbytes拡張子で保存したものを取得
        TextAsset   obj     = (TextAsset)Selection.activeObject;
        AesCryptography aesCryptography = new AesCryptography();

        byte[]  decryptData = aesCryptography.Decrypt( obj.bytes );

        //保存するパスを選択
        string exportPath   = EditorUtility.OpenFolderPanel( "保存するフォルダを選択してください", Application.dataPath, "" );
        if( exportPath == null )
        {
            Debug.LogError( "選択時にエラーが発生しました" );
            return;
        }

        // 復号化したファイルを保存
        File.WriteAllBytes( exportPath + "/" + obj.name + SaveExtension, decryptData );
    }

}

こんな感じです。

#最後に#
記事中にまずい点等あれば指摘頂けると幸いです。

##追記##
Assetが暗号化、復号化されているかは、バイナリエディタにファイルを投げて確認していました(bz)。

現在Android端末にて動作を確認中なのですが、うまく動作していないようです。何か分かり次第こちらにて共有させて頂こうと思います。
Android、iOS、WebPlayerにて動作を確認したところ、問題なく動いているようです。
確認の仕方にミスがあったようです。

62
63
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
62
63

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?