近年、世界的にセキュリティ意識が高まってきたのでC#でAES暗号するコードを実装してみました。
目次
スポンサーリンク
AES暗号とは?
AES(Advanced Encryption Standard)はRijndaelとも呼ばれています。
旧規格の対称鍵暗号であるDES(Data Encryption Standard)の安全性が低下したために、NIST(アメリカ国立標準技術研空所)が公募し、2000年に選定された対称暗号です。
そのため、DESは今となっては非推奨のレガシーテクノロジーとなっているため、AESが推奨とされています。
尚、AES以外にもDES/3DESやRC 4などの暗号化技術がありますが、AESが一番強固と言われています。
AESの鍵長
AESは鍵長によって安全性が異なっており、長さはbit数で表されます。
鍵長が長くなるほどセキュリティは高くなりますが、計算量が増えるのでシステムのパフォーマンスによって鍵長を決定する必要があります。
- 128bit (AES-128)
- 192bit (AES-192)
- 256bit (AES-256)
AES-256暗号を実装してみた
それでは実際にAES暗号するためのコードを書いてみます。今回は鍵長が長めのAES-256を実装しました。
セキュリティに絡むことなので難しそうですが、C#ではSystem.Security.Cryptography.RijndaelManagedクラスを使うことで簡単に実装することができます。
サンプルコード
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace AesSample
{
class Program
{
// 初期化ベクトル"<半角16文字(1byte=8bit, 8bit*16=128bit>"
private const string AES_IV_256 = @"pf69DL6GrWFyZcMK";
// 暗号化鍵<半角32文字(8bit*32文字=256bit)>
private const string AES_Key_256 = @"5TGB&YHN7UJM(IK<5TGB&YHN7UJM(IK<";
static void Main(string[] args)
{
// 平文の文字列
string plainText = "Hello, World!";
Console.WriteLine("PlainText : {0}\n", plainText);
// 暗号化された文字列
string cipher = Encrypt(plainText, AES_IV_256, AES_Key_256);
Console.WriteLine("Cipher : {0}\n", cipher);
Console.WriteLine("Decrypted : {0}\n", Decrypt(cipher, AES_IV_256, AES_Key_256));
Console.ReadLine();
}
/// <summary>
/// 対称鍵暗号を使って文字列を暗号化する
/// </summary>
/// <param name="text">暗号化する文字列</param>
/// <param name="iv">対称アルゴリズムの初期ベクター</param>
/// <param name="key">対称アルゴリズムの共有鍵</param>
/// <returns>暗号化された文字列</returns>
public static string Encrypt(string text, string iv, string key)
{
using (RijndaelManaged myRijndael = new RijndaelManaged())
{
// ブロックサイズ(何文字単位で処理するか)
myRijndael.BlockSize = 128;
// 暗号化方式はAES-256を採用
myRijndael.KeySize = 256;
// 暗号利用モード
myRijndael.Mode = CipherMode.CBC;
// パディング
myRijndael.Padding = PaddingMode.PKCS7;
myRijndael.IV = Encoding.UTF8.GetBytes(iv);
myRijndael.Key = Encoding.UTF8.GetBytes(key);
// 暗号化
ICryptoTransform encryptor = myRijndael.CreateEncryptor(myRijndael.Key, myRijndael.IV);
byte[] encrypted;
using (MemoryStream mStream = new MemoryStream())
{
using (CryptoStream ctStream = new CryptoStream(mStream, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter sw = new StreamWriter(ctStream))
{
sw.Write(text);
}
encrypted = mStream.ToArray();
}
}
// Base64形式(64種類の英数字で表現)で返す
return (System.Convert.ToBase64String(encrypted));
}
}
/// <summary>
/// 対称鍵暗号を使って暗号文を復号する
/// </summary>
/// <param name="cipher">暗号化された文字列</param>
/// <param name="iv">対称アルゴリズムの初期ベクター</param>
/// <param name="key">対称アルゴリズムの共有鍵</param>
/// <returns>復号された文字列</returns>
public static string Decrypt(string cipher, string iv, string key)
{
using (RijndaelManaged rijndael = new RijndaelManaged())
{
// ブロックサイズ(何文字単位で処理するか)
rijndael.BlockSize = 128;
// 暗号化方式はAES-256を採用
rijndael.KeySize = 256;
// 暗号利用モード
rijndael.Mode = CipherMode.CBC;
// パディング
rijndael.Padding = PaddingMode.PKCS7;
rijndael.IV = Encoding.UTF8.GetBytes(iv);
rijndael.Key = Encoding.UTF8.GetBytes(key);
ICryptoTransform decryptor = rijndael.CreateDecryptor(rijndael.Key, rijndael.IV);
string plain = string.Empty;
using (MemoryStream mStream = new MemoryStream(System.Convert.FromBase64String(cipher)))
{
using (CryptoStream ctStream = new CryptoStream(mStream, decryptor, CryptoStreamMode.Read))
{
using (StreamReader sr = new StreamReader(ctStream))
{
plain = sr.ReadLine();
}
}
}
return plain;
}
}
}
}
実行結果
PlainText : Hello, World!
Cipher : /NYRDYOCN8ra6GiGEuzw/w==
Decrypted : Hello, World!
C#でみんなが買っている本
「C#の本」人気ランキングになります。
スクロールできます
ランク | 製品 | 特徴と評価 | 価格 |
---|---|---|---|
1 | 1週間でC#の基礎が学べる本 | 7日間で基礎力が身に付く 評価 | 単行本 2,750円 Kindle 2,475円 |
2 | なるほどなっとくC#入門 | 厳選した機能を学べる 評価 | 単行本 3,168円 Kindle 3,010円 |
コメント