AESで暗号化と復号化
2021-05-27

AES

本日はAESでデータを暗号化と復号化する方法を紹介。
AESは通信データの暗号化方法のひとつで、Advanced Encryption Standardの略になります。
C#のAESの使い方はこちらのドキュメントを参照ください。 https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.aes?view=net-5.0
サンプルは下記のようになります。 ソースコードを参照する場合はこちらのGitを参照ください。 aes-encryption-example-01
using System; using System.IO; using System.Security.Cryptography; namespace Aes_Example { class AesExample { public static void Main() { string original = "Here is some data to encrypt!"; // Create a new instance of the Aes // class. This generates a new key and initialization // vector (IV). using (Aes myAes = Aes.Create()) { // Encrypt the string to an array of bytes. byte[] encrypted = EncryptStringToBytes_Aes(original, myAes.Key, myAes.IV); // Decrypt the bytes to a string. string roundtrip = DecryptStringFromBytes_Aes(encrypted, myAes.Key, myAes.IV); //Display the original data and the decrypted data. Console.WriteLine("Original: {0}", original); Console.WriteLine("Round Trip: {0}", roundtrip); } } static byte[] EncryptStringToBytes_Aes(string plainText, byte[] Key, byte[] IV) { // Check arguments. if (plainText == null || plainText.Length <= 0) throw new ArgumentNullException("plainText"); if (Key == null || Key.Length <= 0) throw new ArgumentNullException("Key"); if (IV == null || IV.Length <= 0) throw new ArgumentNullException("IV"); byte[] encrypted; // Create an Aes object // with the specified key and IV. using (Aes aesAlg = Aes.Create()) { aesAlg.Key = Key; aesAlg.IV = IV; // Create an encryptor to perform the stream transform. ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV); // Create the streams used for encryption. using (MemoryStream msEncrypt = new MemoryStream()) { using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) { using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) { //Write all data to the stream. swEncrypt.Write(plainText); } encrypted = msEncrypt.ToArray(); } } } // Return the encrypted bytes from the memory stream. return encrypted; } static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key, byte[] IV) { // Check arguments. if (cipherText == null || cipherText.Length <= 0) throw new ArgumentNullException("cipherText"); if (Key == null || Key.Length <= 0) throw new ArgumentNullException("Key"); if (IV == null || IV.Length <= 0) throw new ArgumentNullException("IV"); // Declare the string used to hold // the decrypted text. string plaintext = null; // Create an Aes object // with the specified key and IV. using (Aes aesAlg = Aes.Create()) { aesAlg.Key = Key; aesAlg.IV = IV; // Create a decryptor to perform the stream transform. ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV); // Create the streams used for decryption. using (MemoryStream msDecrypt = new MemoryStream(cipherText)) { using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) { using (StreamReader srDecrypt = new StreamReader(csDecrypt)) { // Read the decrypted bytes from the decrypting stream // and place them in a string. plaintext = srDecrypt.ReadToEnd(); } } } } return plaintext; } } }
暗号化
暗号化はこのラインで行われています。
byte[] encrypted = EncryptStringToBytes_Aes(original, myAes.Key, myAes.IV);
ここではKey
とIV
を指定しています。 IV
はInitialize Vector
の略で暗号化する際に初期必要となる値になります。
EncryptStringToBytes_Aes
メソッドは別メソッドとして下記のように作成しています。
static byte[] EncryptStringToBytes_Aes(string plainText, byte[] Key, byte[] IV) { // Check arguments. if (plainText == null || plainText.Length <= 0) throw new ArgumentNullException("plainText"); if (Key == null || Key.Length <= 0) throw new ArgumentNullException("Key"); if (IV == null || IV.Length <= 0) throw new ArgumentNullException("IV"); byte[] encrypted; // Create an Aes object // with the specified key and IV. using (Aes aesAlg = Aes.Create()) { aesAlg.Key = Key; aesAlg.IV = IV; // Create an encryptor to perform the stream transform. ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV); // Create the streams used for encryption. using (MemoryStream msEncrypt = new MemoryStream()) { using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) { using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) { //Write all data to the stream. swEncrypt.Write(plainText); } encrypted = msEncrypt.ToArray(); } } } // Return the encrypted bytes from the memory stream. return encrypted; }
復号化
暗号化されたものを基に戻すには下記で処理されています。
// Decrypt the bytes to a string. string roundtrip = DecryptStringFromBytes_Aes(encrypted, myAes.Key, myAes.IV);
実際に処理されるメソッドは下記になります。
static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key, byte[] IV) { // Check arguments. if (cipherText == null || cipherText.Length <= 0) throw new ArgumentNullException("cipherText"); if (Key == null || Key.Length <= 0) throw new ArgumentNullException("Key"); if (IV == null || IV.Length <= 0) throw new ArgumentNullException("IV"); // Declare the string used to hold // the decrypted text. string plaintext = null; // Create an Aes object // with the specified key and IV. using (Aes aesAlg = Aes.Create()) { aesAlg.Key = Key; aesAlg.IV = IV; // Create a decryptor to perform the stream transform. ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV); // Create the streams used for decryption. using (MemoryStream msDecrypt = new MemoryStream(cipherText)) { using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) { using (StreamReader srDecrypt = new StreamReader(csDecrypt)) { // Read the decrypted bytes from the decrypting stream // and place them in a string. plaintext = srDecrypt.ReadToEnd(); } } } } return plaintext; }
テストと実装
それでは暗号化復号化を実装するためのフロントのコードを書いてテストしてみます。
フロントのコードはこちら
@{ ViewData["Title"] = "Home Page"; } @using wppAesExample.Controllers @model HomeController.EncrypDecryptViewModel <div class="container"> <div class="row"> <div class="col-md-6"> <form method="post" action="/Encrypt"> @Html.AntiForgeryToken() <div class="py-2"> <label> 暗号化したいText </label> <input type="text" class="form-control" name="original" value="@Model.OriginalText" /> </div> <div class="py-2"> <label> 暗号化されたTEXT </label> <textarea class="form-control" rows="5" readonly>@Model.EncryptedText</textarea> </div> <div class="py-2"> <label> 復号かされたTEXT </label> <input type="text" class="form-control" readonly value="@Model.DecryptedText" /> </div> <div class="py-2"> <button type="submit" class="btn btn-primary rounded-0"> 暗号化 </button> </div> </form> </div> </div> </div>
実装したときの画面はこちらです。
まとめ
ここに記載されているコードカプセル化して利用することによって簡単に暗号化されたデータを格納し、再度利用するときに復号化することができます。
公開日: 2021-05-18