LoginSignup
13
23

More than 5 years have passed since last update.

C#でファイルのAES暗号化

Posted at

ファイル暗号化クラス

ファイルの暗号化、復号化を行うためのクラス。

引数には、それぞれ入力ファイルストリーム、出力ファイルストリーム、パスワードを入力。

FileEncryptor
using System;
using System.Security.Cryptography;
using System.Text;
using System.IO;

namespace EncryptTest
{
    /// <summary>
    /// File Encryptor Class
    /// </summary>
    public static class FileEncryptor
    {
        /// <summary>
        /// Key Length
        /// </summary>
        public const int KeyLength = 16;

        /// <summary>
        /// Generate Byte Key from Password
        /// </summary>
        /// <returns>Byte Key</returns>
        /// <param name="password">Password</param>
        private static byte[] GenerateByteKey(string password)
        {
            /* Get Bytes of Password */
            var bytesPassword = Encoding.UTF8.GetBytes(password);
            /* Create Bytes Key Array */
            var bytesKey = new byte[KeyLength];

            /* Loop to Key Length */
            for(int i = 0; i < KeyLength; i++)
            {
                /* Copy Password Byte Array and fill remain bytes by 0 */
                bytesKey[i] = (i < bytesPassword.Length) ? bytesPassword[i] : (byte)0;
            }

            return bytesKey;
        }

        /// <summary>
        /// Encrypt File
        /// </summary>
        /// <param name="ifs">Input File Stream</param>
        /// <param name="ofs">Output File Stream</param>
        /// <param name="password">Password</param>
        public static void Encrypt(Stream ifs, Stream ofs, string password)
        {
            /* Generate Byte Key from Password */
            var bytesKey = FileEncryptor.GenerateByteKey(password);

            /* Create AES Crypto Service Provider */
            var aes = new AesCryptoServiceProvider() {
                BlockSize = 128,
                KeySize = 128,
                Mode = CipherMode.CBC,
                Padding = PaddingMode.PKCS7,
                Key = bytesKey,
            };

            /* Generate Random Initialization Vector(IV) */
            aes.GenerateIV();

            /* Get IV */
            var bytesIV = aes.IV;

            /* Write IV to File (128bit=16bytes) */
            ofs.Write(bytesIV, 0, 16);

            /* Create AES Encryptor */
            using(var encrypt = aes.CreateEncryptor())
            {
                /* Create Crypto Stream */
                using(var cs = new CryptoStream(ofs, encrypt, CryptoStreamMode.Write))
                {
                    /* Inifity Loop */
                    while(true)
                    {
                        /* Create Write Buffer */
                        var buffer = new byte[1024];
                        /* Read File to Buffer */
                        var len = ifs.Read(buffer, 0, buffer.Length);

                        /* Read Data Size is larger than 0 */
                        if(len > 0)
                        {
                            /* Write Read Data to Crypto Stream */
                            cs.Write(buffer, 0, len);
                        }
                        else
                        {
                            /* End of Input File */
                            break;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Decrypt File
        /// </summary>
        /// <param name="ifs">Input File Stream</param>
        /// <param name="ofs">Output File Stream</param>
        /// <param name="password">Password</param>
        public static void Decrypt(Stream ifs, Stream ofs, string password)
        {
            /* Generate Byte Key from Password */
            var bytesKey = FileEncryptor.GenerateByteKey(password);

            /* Create AES Crypto Service Provider */
            var aes = new AesCryptoServiceProvider() {
                BlockSize = 128,
                KeySize = 128,
                Mode = CipherMode.CBC,
                Padding = PaddingMode.PKCS7,
                Key = bytesKey,
            };

            /* Create IV Buffer */
            var bytesIV = new byte[KeyLength];

            /* Read IV from Input File */
            ifs.Read(bytesIV, 0, KeyLength);

            /* Set Read IV */
            aes.IV = bytesIV;

            /* Create AES Decryptor */
            using(var encrypt = aes.CreateDecryptor())
            {
                /* Create Crypto Stream */
                using(var cs = new CryptoStream(ofs, encrypt, CryptoStreamMode.Write))
                {
                    /* Inifinity Loop */
                    while(true)
                    {
                        /* Create Read Buffer */
                        var buffer = new byte[1024];

                        /* Read Input File to Buffer */
                        var len = ifs.Read(buffer, 0, buffer.Length);

                        /* Read Data Size is larger than 0 */
                        if(len > 0)
                        {
                            /* Write Read Data to Crypto Stream */
                            cs.Write(buffer, 0, len);
                        }
                        else
                        {
                            /* End of Data */
                            break;
                        }
                    }
                }
            }
        }
    }
}

Usage

使い方は、
1. 入力ファイル(平文)、出力ファイル(暗号化ファイル)のストリームを生成し、暗号化用パスワードを入力してファイルを暗号化
2. 入力ファイル(暗号化ファイル)、出力ファイル(復号化ファイル)のストリームを生成し、暗号化に使用したパスワードを入力してファイルを復号化

Program.cs
class MainClass
{
    public static void Main(string[] args)
    {   
        /* Create Input File Stream */
        using(var eifs = new FileStream("InputFile.txt", FileMode.Open, FileAccess.Read))
        {
            /* Create Output File Stream*/
            using(var eofs = new FileStream("EncryptedFile.bin", FileMode.Create, FileAccess.Write))
            {
                /* Encrypt File */
                FileEncryptor.Encrypt(eifs, eofs, "Password");
            }
        }

        /* Create Input File Stream */
        using(var difs = new FileStream("EncryptedFile.bin", FileMode.Open, FileAccess.Read))
        {
            /* Create Output File Stream*/
            using(var dofs = new FileStream("DecryptedFile.txt", FileMode.Create, FileAccess.Write))
            {
                /* Decrypt File */
                FileEncryptor.Decrypt(difs, dofs, "Password");
            }
        }
    }
}
13
23
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
23