【Unity】Rijndael による文字列の暗号化・複合化

DEVELOP

暗号化キーを渡して暗号化するシンプルな実装。

using UnityEngine;
using System.Text;
using System.IO;
using System.Security.Cryptography;
 
namespace mira
{
    /// <summary>
    /// Rijndael による暗号化/複合化
    /// </summary>
    public class Encrypt
    {
        private const int AES_BLOCK_SIZE = 128;
        private const int AES_KEY_SIZE = 256;
        private const int AES_IV_SIZE = 16;
 
        private Rijndael rijndael = null;
        private byte[] aesIV;
 
        /// <summary>
        /// コンストラクタ
        /// </summary>
        public Encrypt()
        {
            Init(AES_BLOCK_SIZE, AES_KEY_SIZE);
        }
 
        /// <summary>
        /// 初期化
        /// </summary>
        public void Init(int _aesBlockSize, int _aesKeySize)
        {
            rijndael.Padding = PaddingMode.Zeros;
            rijndael.Mode = CipherMode.CBC;
            rijndael.KeySize = _aesKeySize;
            rijndael.BlockSize = _aesBlockSize;
        }
 
        /// <summary>
        /// AES IV SIZE の取得
        /// </summary>
        public int GetAesIVSize()
        {
            return AES_IV_SIZE;
        }
 
        /// <summary>
        /// AES キーの設定
        /// </summary>
        public void SetAesKey(string _aesKey)
        {
            SetAesKey(Encoding.UTF8.GetBytes(_aesKey));
        }
 
        /// <summary>
        /// AES キーの設定
        /// </summary>
        public void SetAesKey(byte[] _aesKey)
        {
            rijndael.Key = _aesKey;
        }
 
        /// <summary>
        /// IVを生成する
        /// </summary>
        public byte[] CreateIV()
        {
            return Encoding.UTF8.GetBytes(GetNewIV(AES_IV_SIZE));
        }
 
        /// <summary>
        /// 暗号パスワードを設定する
        /// </summary>
        public void SetIV(byte[] _iv)
        {
            rijndael.IV = _iv;
        }
 
        /// <summary>
        /// 現在設定されているIVを取得する
        /// </summary>
        public byte[] GetIV()
        {
            return rijndael.IV;
        }
 
        /// <summary>
        /// Rijndaelを用いた暗号化
        /// </summary>
        private byte[] Encode(byte[] _data)
        {
            byte[] encryptData = new byte[0];
 
            ICryptoTransform encryptor = rijndael.CreateEncryptor();
 
            using (MemoryStream msEncrypt = new MemoryStream())
            {
                using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    csEncrypt.Write(_data, 0, _data.Length);
                    csEncrypt.FlushFinalBlock();
                }
                encryptData = msEncrypt.ToArray();
            }
 
            return encryptData;
        }
 
        /// <summary>
        /// Rijndaelを用いた復号化
        /// </summary>
        public byte[] Decode(byte[] _data)
        {
            byte[] descryptData = new byte[_data.Length];
 
            try
            {
                ICryptoTransform decryptor = rijndael.CreateDecryptor();
 
                using (MemoryStream msDecrypt = new MemoryStream(_data))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        csDecrypt.Read(descryptData, 0, descryptData.Length);
                    }
                }
            }
            catch (CryptographicException e)
            {
                Debug.LogError("[Encrypt] decrypt error: " + e.ToString());
            }
 
            return descryptData;
        }
 
        private string GetNewIV(int _length)
        {
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
 
            // 文字コードの範囲
            int CharCodeRange = ((int)('z' - '0')) + 1;
            // パスワードの文字コード配列
            byte[] aryBytePassword = new byte[_length];
            // 文字コード
            int iCharCode;
 
            // パスワード文字コード配列の作成
            for (int i = 0; i < aryBytePassword.Length; i++)
            {
                byte[] bs = new byte[4];
                rng.GetBytes(bs);
                int wk = System.BitConverter.ToInt32(bs, 0);
                iCharCode = Mathf.Abs(wk % CharCodeRange);
                iCharCode += (int)'0';
 
                // 文字コードをバイト配列に設定
                aryBytePassword[i] = (byte)iCharCode;
            }
 
            // バイト配列をASCII文字列に置換
            return Encoding.ASCII.GetString(aryBytePassword);
        }
    }
}

使い方

var str = "hello";
var data = System.Text.Encoding.UTF8.GetBytes(str);
 
var encrypt = new mira.Encrypt();
var encodeBytes = encrypt.Encode(data);
var decodeBytes = encrypt.Decode(encodeBytes);
 
var check = System.Text.Encoding.UTF8.GetString(decodeBytes);
Debug.Log(check);

Posted by kazupon