single.php

AesCryptoServiceProvider を使って画像を暗号化する

AES知ってますか?暗号化・復号の1つですが、C#のAesCryptoServiceProvider を使うと、簡単に文字列などの暗号化・復号するプログラムが出来てしまいます。

AES(Advanced Encryption Standard)

DESに代わる標準暗号アルゴリズムで、暗号化と復号を行う場合によく使われる方式。C#やJavaでも使われるためプラットフォームを超えて暗号化→複合するような場合でもAESであれば互換性が保持できる。

今回はC#のAesCryptoServiceProviderクラスを利用するためサンプルコードはC#用です。Javaの場合も構文的には、ほぼ同じです。

暗号化

まずは、暗号化するコードです。入出力用のファイルのパスと、復号用のパスワードを使って、AesCryptoServiceProvider を使ってAESアルゴリズムの暗号化を行います。

public static void Encrypt(string sInPath, string sOutPath, string sPassword)
{
  System.Security.Cryptography.AesCryptoServiceProvider aes = new System.Security.Cryptography.AesCryptoServiceProvider();
  aes.BlockSize = 128;
  aes.KeySize = 128;
  aes.Mode = System.Security.Cryptography.CipherMode.CBC;
  aes.Padding = System.Security.Cryptography.PaddingMode.PKCS7;

  aes.GenerateIV();
  byte[] bytesIV = aes.IV;

  byte[] bytesPassword = System.Text.Encoding.UTF8.GetBytes(sPassword);
  byte[] bytesKey = new byte[16];

  for (int nLoop = 0; nLoop < 16; nLoop++)
  {
    if (nLoop < bytesPassword.Length)
    {
    bytesKey[nLoop] = bytesPassword[nLoop];
    }
    else
    {
    bytesKey[nLoop] = 0;
   }
  }
  aes.Key = bytesKey;
  System.Security.Cryptography.ICryptoTransform encrypt = aes.CreateEncryptor();
  System.IO.FileStream outFileStream = new System.IO.FileStream(sOutPath, System.IO.FileMode.Create, System.IO.FileAccess.Write);
  string sHeader = "SAMPLE";
  byte[] bytesHeader = System.Text.Encoding.UTF8.GetBytes(sHeader);
  outFileStream.Write(bytesHeader, 0, 6);
  outFileStream.Write(bytesKey, 0, 16);
  outFileStream.Write(bytesIV, 0, 16);
  System.Security.Cryptography.CryptoStream cs = new System.Security.Cryptography.CryptoStream(outFileStream, encrypt, System.Security.Cryptography.CryptoStreamMode.Write);
  System.IO.FileStream fs = new System.IO.FileStream(sInPath, System.IO.FileMode.Open, System.IO.FileAccess.Read);
  byte[] buffer = new byte[1024];
  int nLength;

  while ((nLength = fs.Read(buffer, 0, buffer.Length)) > 0)
  {
    cs.Write(buffer, 0, nLength);
  }

  fs.Close();
  cs.Close();
  encrypt.Dispose();
  outFileStream.Close();
}

復号

続いて復号するコードです。暗号化する際に復号用のパスワードはファイル内に埋め込んであるので、ファイルを展開してパスワードを読み取り、ファイルを復号します。

public static void Decrypt(string sInPath, string sOutPath, string sPassword)
{
  System.Security.Cryptography.AesCryptoServiceProvider aes = new System.Security.Cryptography.AesCryptoServiceProvider();
  aes.BlockSize = 128;
  aes.KeySize = 128;
  aes.Mode = System.Security.Cryptography.CipherMode.CBC;
  aes.Padding = System.Security.Cryptography.PaddingMode.PKCS7;

  byte[] bytesHeader = new byte[6];
  byte[] bytesPassword = System.Text.Encoding.UTF8.GetBytes(sPassword);
  byte[] bytesKey = new byte[16];
  byte[] bytesIV = new byte[16];

  System.IO.FileStream fs = new System.IO.FileStream(sInPath, System.IO.FileMode.Open, System.IO.FileAccess.Read);
  fs.Read(bytesHeader, 0, 6);
  fs.Read(bytesKey, 0, 16);
  fs.Read(bytesIV, 0, 16);

  aes.Key = bytesKey;
  aes.IV = bytesIV;

  System.Security.Cryptography.ICryptoTransform decrypt = aes.CreateDecryptor();
  System.IO.FileStream outFileStream = new System.IO.FileStream(sOutPath, System.IO.FileMode.Create, System.IO.FileAccess.Write);
  System.Security.Cryptography.CryptoStream cs = new System.Security.Cryptography.CryptoStream(outFileStream, decrypt, System.Security.Cryptography.CryptoStreamMode.Write);

  byte[] buffer = new byte[1024];
  int nLength;

  while ((nLength = fs.Read(buffer, 0, buffer.Length)) > 0)
  {
    cs.Write(buffer, 0, nLength);
  }

  fs.Close();
  cs.Close();
  decrypt.Dispose();
  outFileStream.Close();
}

まとめ

過去のコードから、AES暗号化と復号の部分を備忘録的に投稿してみました。C#の場合、System.Security.Cryptography アセンブリにAES以外にも暗号化や複合を行う便利な関数が用意されています。

AESはC#のほか、C++やJavaなど、ほとんどの言語でサポートされているので仕様を合わせることで、プラットホームを超えた使い方ができるようになります。

スポンサーリンク

最後までご覧いただき、ありがとうございます。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です