暗号化、復号化

文字列の暗号化ってよくやるよね。

X.509 証明書は以下
方法: X.509 証明書で XML 要素を暗号化する | Microsoft Docs

AESを使用した暗号化。
インスタンスの方はいらないかも。

/// <summary>
/// 暗号化を行う機能を提供します。
/// </summary>
public class Encryptor {
  /// <summary>
  /// 暗号化に使用するキーを取得、または設定します。
  /// </summary>
  public byte[] Key { get; set; }

  /// <summary>
  /// 暗号化に使用する初期化ベクタを取得、または設定します。
  /// </summary>
  public byte[] IV { get; set; }

  /// <summary>
  /// Encryptor クラスの新しいインスタンスを初期化します。
  /// </summary>
  public Encryptor() {
  }

  /// <summary>
  /// 指定されたソースを暗号化します。
  /// </summary>
  /// <param name="source">暗号化するソース。</param>
  /// <returns>暗号化されたバイト配列。</returns>
  public byte[] EncryptSource( byte[] source ) {
    return EncryptSource( source, Key, IV );
  }

  /// <summary>
  /// UTF-8エンコーディング、キー、初期化ベクタを指定して文字列を暗号化します。
  /// </summary>
  /// <param name="source">暗号化するソース。</param>
  /// <param name="key">暗号化に使用するキー。</param>
  /// <param name="IV">暗号化に使用する初期化ベクタ。</param>
  /// <returns>暗号化されたバイト配列。</returns>
  static public byte[] EncryptSource( string source, byte[] key, byte[] IV ) {
    return EncryptSource( Encoding.UTF8, source, key, IV );
  }

  /// <summary>
  /// キー、初期化ベクタを指定して文字列を暗号化します。
  /// </summary>
  /// <param name="encoding">暗号化に使用するエンコーディング。</param>
  /// <param name="source">暗号化するソース。</param>
  /// <param name="key">暗号化に使用するキー。</param>
  /// <param name="IV">暗号化に使用する初期化ベクタ。</param>
  /// <returns>暗号化されたバイト配列。</returns>
  static public byte[] EncryptSource( Encoding encoding, string source, byte[] key, byte[] IV ) {
    return EncryptSource( encoding.GetBytes( source ), key, IV );
  }

  /// <summary>
  /// キー、初期化ベクタを指定してソースを暗号化します。
  /// </summary>
  /// <param name="source">暗号化するソース。</param>
  /// <param name="key">暗号化に使用するキー。</param>
  /// <param name="IV">暗号化に使用する初期化ベクタ。</param>
  /// <returns>暗号化されたバイト配列。</returns>
  static public byte[] EncryptSource( byte[] source, byte[] key, byte[] IV ) {
    Aes aes = Aes.Create();

    using (MemoryStream ms = new MemoryStream()) {
      using (CryptoStream cs = new CryptoStream( ms
        , aes.CreateEncryptor( key, IV )
        , CryptoStreamMode.Write
      )) {
        cs.Write( source, 0, source.Length );
        cs.FlushFinalBlock();
        return ms.ToArray();
      }
    }
  }

  /// <summary>
  /// 指定された文字列を元に key を生成します。
  /// </summary>
  /// <param name="source">key の元となるソース。</param>
  /// <returns>生成された key。</returns>
  /// <remarks>key は UTF-8 の文字列を指定します。</remarks>
  public static byte[] CreateKey( string source ) {
    SHA256 hasher = SHA256.Create();

    return hasher.ComputeHash( Encoding.UTF8.GetBytes( source ) );
  }

  /// <summary>
  /// バイト配列を Decryptor が利用可能な文字列に変換します。
  /// </summary>
  /// <param name="source">暗号化されたバイト配列。</param>
  /// <returns>変換された Decryptor が利用可能な文字列。</returns>
  public static string EncriptedBytesToString( byte[] source ) {
    return BitConverter.ToString( source ).Replace( "-", "" ).ToLower();
  }
}

復号化

/// <summary>
/// 復号化を行う機能を提供します。
/// </summary>
public class Decryptor {
  /// <summary>
  /// キー、初期化ベクタを指定してソースを復号化します。
  /// </summary>
  /// <param name="cipher">復号化する暗号。</param>
  /// <param name="key">復号化に使うキー。</param>
  /// <param name="IV">復号化に使用する初期化ベクタ。</param>
  /// <returns>復号化された文字列。</returns>
  static public byte[] DecryptSource( byte[] cipher, byte[] key, byte[] IV ) {
    Aes aes = Aes.Create();

    using (MemoryStream ms = new MemoryStream()) {
      using (CryptoStream cs = new CryptoStream( ms
        , aes.CreateDecryptor( key, IV )
        , CryptoStreamMode.Write
      )) {

        cs.Write( cipher, 0, cipher.Length );
        cs.FlushFinalBlock();
        return ms.ToArray();
      }
    }
  }

  static public byte[] DecryptSource( string cipher, byte[] key, byte[] IV ) {
    byte[] bytes = new byte[cipher.Length/2];

    for ( int i = 0; i < bytes.Length; i++ ) {
      bytes[i] = byte.Parse( (
        cipher[i * 2].ToString() + cipher[i * 2 + 1].ToString() )
        , NumberStyles.HexNumber
      );
    }

    return DecryptSource( bytes, key, IV );
  }
}


使い方
暗号化

var aes = Aes.Create();
byte[] IV =  aes.GenerateIV();
byte[] Key = aes.GenerateKey();

Console.WriteLine( Encryptor.EncriptedBytesToString(Encryptor.EncryptSource("暗号する文",Key,IV)));

復号化

byte[] source = Decryptor.DecryptSource( "Encryptor.EncriptedBytesToStringされた文字列", Key, IV );
Console.WriteLine( Encoding.UTF8.GetString( source ) );