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など、ほとんどの言語でサポートされているので仕様を合わせることで、プラットホームを超えた使い方ができるようになります。
スポンサーリンク
最後までご覧いただき、ありがとうございます。