본문 바로가기

Programing/.NET

[C#] AES256(AES/CBC/PKCS5Padding) 암/복호화

 

.NET 에서 AES256(AES/CBC/PKCS5Padding) 방식으로 암호화 복호화하는 방식이다.

 

 

1. HexString 방식의 Key / IV생성 

using System;
using System.Web;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using Newtonsoft.Json.Serialization;
using System.Collections.Generic;
using System.Reflection;

namespace Study.Model
{
    public sealed class Crypto
    {
    	
        ...
        
        //Key / Iv 생성
        public static void GenerateKeyAndIV()
        {
            // This code is only here for an example
            RijndaelManaged myRijndaelManaged = new RijndaelManaged();
            myRijndaelManaged.Mode = CipherMode.CBC;
            myRijndaelManaged.Padding = PaddingMode.PKCS7;

            myRijndaelManaged.GenerateIV();
            myRijndaelManaged.GenerateKey();
            string newKey = ByteArrayToHexString(myRijndaelManaged.Key);
            string newinitVector = ByteArrayToHexString(myRijndaelManaged.IV);
        }
        
        //ByteArray > HexString 으로 변환
        public static string ByteArrayToHexString(byte[] ba)
        {
            StringBuilder hex = new StringBuilder(ba.Length * 2);
            foreach (byte b in ba)
                hex.AppendFormat("{0:x2}", b);
            return hex.ToString();
        }
    }
}

 

 

2. 암호화/복호화 

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace Study.Model
{
    public sealed class Crypto
    {
        protected RijndaelManaged myRijndael;

        private static string encryptionKey = "KEY 값";
        private static string initialisationVector = "IV값";

        // Singleton pattern used here with ensured thread safety
        protected static readonly Crypto _instance = new Crypto();
        public static Crypto Instance
        {
            get { return _instance; }
        }


        public Crypto()
        {

        }


        //복호화
        public string DecryptText(string encryptedString)
        {
            try
            {
                using (myRijndael = new RijndaelManaged())
                {
                    //key,iv 값의 인코딩방식에 따라 byte변환을 달리해야한다
                    myRijndael.Key = HexStringToByte(encryptionKey);
                    myRijndael.IV = HexStringToByte(initialisationVector);
                    myRijndael.Mode = CipherMode.CBC;
                    myRijndael.Padding = PaddingMode.PKCS7;

                    Byte[] ourEnc = Convert.FromBase64String(encryptedString);
                    string ourDec = DecryptStringFromBytes(ourEnc, myRijndael.Key, myRijndael.IV);

                    return ourDec;
                }
            }
            catch (Exception e)
            {
                return encryptedString;
            }
        }

        //암호화 
        public string EncryptText(string plainText)
        {
            try
            {
                using (myRijndael = new RijndaelManaged())
                {

                    //key,iv 값의 인코딩방식에 따라 byte변환을 달리해야한다
                    myRijndael.Key = HexStringToByte(encryptionKey);
                    myRijndael.IV = HexStringToByte(initialisationVector);
                    myRijndael.Mode = CipherMode.CBC;
                    myRijndael.Padding = PaddingMode.PKCS7;

                    byte[] encrypted = EncryptStringToBytes(plainText, myRijndael.Key, myRijndael.IV);
                    string encString = Convert.ToBase64String(encrypted);

                    return encString;
                }
            }
            catch (Exception e)
            {
                return plainText;
            }
        }

        //Byte를 EncryptString으로 변환 
        protected byte[] EncryptStringToBytes(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("Key");
            byte[] encrypted;
            // Create an RijndaelManaged object 
            // with the specified key and IV. 
            using (RijndaelManaged rijAlg = new RijndaelManaged())
            {
                rijAlg.Key = Key;
                rijAlg.IV = IV;

                // Create a decrytor to perform the stream transform.
                ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.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;

        }

        //Byte를 복호화된 스트링으로 변환
        protected string DecryptStringFromBytes(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("Key");

            // Declare the string used to hold 
            // the decrypted text. 
            string plaintext = null;

            // Create an RijndaelManaged object 
            // with the specified key and IV. 
            using (RijndaelManaged rijAlg = new RijndaelManaged())
            {
                rijAlg.Key = Key;
                rijAlg.IV = IV;

                // Create a decrytor to perform the stream transform.
                ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.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;
        }

        //BASE64 인코딩된 키 , IV 값 Byte변환
        protected static byte[] Base64StringToByte(string base64String)
        {
            try
            {
                return Convert.FromBase64String(encryptionKey);
            }
            catch (Exception e)
            {
                throw;
            }
        }

        //UTF8 인코딩된 키 , IV 값 Byte변환
        protected static byte[] Utf8StringToByte(string utf8String)
        {
            try
            {
                byte[] bytes = Encoding.UTF8.GetBytes(utf8String);
                return bytes;
            }
            catch (Exception e)
            {
                throw;
            }
        }

        //HexString KEY , IV 값 Byte변환
        protected static byte[] HexStringToByte(string hexString)
        {
            try
            {
                int bytesCount = (hexString.Length) / 2;
                byte[] bytes = new byte[bytesCount];
                for (int x = 0; x < bytesCount; ++x)
                {
                    bytes[x] = Convert.ToByte(hexString.Substring(x * 2, 2), 16);
                }
                return bytes;
            }
            catch (Exception e)
            {
                throw;
            }
        }
    }
}

 

위코드에서 Key , IV 의 인코딩 방식에 따라 myRijndael.Key 값에 Byte를 넣어줄때 변환하는 방식이 각각 달라야한다.

 

 

사용방법

Crypto crypto = new Crypto()

string decryptTxt = crypto.DecryptText(encryptText);
string encryptTxt = crypto.DecryptText(decryptText);

'Programing > .NET' 카테고리의 다른 글

[C#] BarcodeLib 바코드 생성  (0) 2021.11.10
[C#]SFTP 파일 업로드  (0) 2021.11.08
[C#] RestSharp 으로 HTTP/HTTPS 통신  (0) 2020.07.24
[C#] Log파일 생성  (0) 2019.07.30
[C#]EUC-KR UTF8변환  (0) 2018.08.01