【Unity】Rijndael による文字列の暗号化・複合化
暗号化キーを渡して暗号化するシンプルな実装。
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);