C#에서 AES256으로 암호화 하기

c# AES256 예제화면

예전부터 한번 해봐야지 하고 생각만 하다가 안했던 암호화처리

요즘은 나름 보안에 관심을 가져야 겠다 라는 생각에 데이터 네트워크로 송수신할때 암호화는 적용해야 하지 않을까 라는 생각에 간단한 예제 해봄.

암호화에 대한 기초 지식은 https://www.slideshare.net/ssuser800974/ss-76664853 를 참고함

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

namespace AESTest2
{
    class AESEncrypt
    {
        private SHA256Managed sha256Managed = new SHA256Managed();
        private RijndaelManaged aes = new RijndaelManaged();

        public AESEncrypt()
        {
            aes.KeySize = 256;
            aes.BlockSize = 128;
            aes.Mode = CipherMode.CBC;
            aes.Padding = PaddingMode.PKCS7;
        }


        //AES_256 암호화
        public byte[] AESEncrypt256(byte[] encryptData, String password)
        {
            // Salt는 비밀번호의 길이를 SHA256 해쉬값으로 한다.
            var salt = sha256Managed.ComputeHash(Encoding.UTF8.GetBytes(password.Length.ToString()));
            Console.WriteLine("Salt(Base64) : " + Convert.ToBase64String(salt));


            //PBKDF2(Password-Based Key Derivation Function)
            //반복은 65535번
            var PBKDF2Key   = new Rfc2898DeriveBytes(password, salt, 65535, HashAlgorithmName.SHA256);
            var secretKey   = PBKDF2Key.GetBytes(aes.KeySize / 8);
            var iv          = PBKDF2Key.GetBytes(aes.BlockSize / 8);

            Console.WriteLine("SecretKey(Base64) : " + Convert.ToBase64String(secretKey));
            Console.WriteLine("IV(Base64) : " + Convert.ToBase64String(iv));

            byte[] xBuff = null;
            using (var ms = new MemoryStream())
            {
                using (var cs = new CryptoStream(ms, aes.CreateEncryptor(secretKey, iv), CryptoStreamMode.Write))
                {
                    cs.Write(encryptData, 0, encryptData.Length);
                }
                xBuff = ms.ToArray();
            }
            return xBuff;
        }

        //AES_256 복호화
        public byte[] AESDecrypt256(byte[] decryptData, String password)
        {
            // Salt는 비밀번호의 길이를 SHA256 해쉬값으로 한다.
            var salt = sha256Managed.ComputeHash(Encoding.UTF8.GetBytes(password.Length.ToString()));

            //PBKDF2(Password-Based Key Derivation Function)
            //반복은 65535번
            var PBKDF2Key = new Rfc2898DeriveBytes(password, salt, 65535, HashAlgorithmName.SHA256);
            var secretKey = PBKDF2Key.GetBytes(aes.KeySize / 8);
            var iv = PBKDF2Key.GetBytes(aes.BlockSize / 8);

            byte[] xBuff = null;
            using (var ms = new MemoryStream())
            {
                using (var cs = new CryptoStream(ms, aes.CreateDecryptor(secretKey, iv), CryptoStreamMode.Write))
                {
                    cs.Write(decryptData, 0, decryptData.Length);
                }
                xBuff = ms.ToArray();
            }
            return xBuff;
        }

    }

    class Program
    {
        static void Main(string[] args)
        {
            AESEncrypt aes = new AESEncrypt();
            var planeText = "https://linsoo.co.kr";
            var password = "비밀번호";

            Console.WriteLine("오리지널 문장 : "+planeText);
            Console.WriteLine("대칭키로 쓰일 키 : " + password);
            Console.WriteLine("
");

            //스트링을 byte배열로 변환
            var byteArray = Encoding.UTF8.GetBytes(planeText);

            //AES256으로 인크립트
            byte[] encryptedArray = aes.AESEncrypt256(byteArray, password);
            Console.WriteLine("
");
            Console.WriteLine("인크립트 된 문자열 : " + Encoding.UTF8.GetString(encryptedArray));

            //디크립트(AES256)
            byte[] decryptedArray = aes.AESDecrypt256(encryptedArray, password);
            var decryptedString = Encoding.UTF8.GetString(decryptedArray);
            Console.WriteLine("디크립트 된 문자열 : " + decryptedString);
            Console.WriteLine("
");
        }
    }
}

다른 예제들 보면 대부분 IV 값을 0으로 넣는데 인터넷으로 찾아본걸로 의하면 IV값이 0이면 큰 의미는 없을거 같아서 이래저래 찾아보니 패스워드 키값을 가지고 이래저래 섞어서 쓰는법을 쓰길래 적용함.

반복은 많이 할수록 느려지지만 그만큼 풀기가 힘들어진다고 함.

암튼 그래서 위와 같은 방식으로 작업 완료.

C#에서는 기본적으로 제공되는 함수가 많아서 편리하고 간단하게 작업됨.

암호화에 대해 여기저기 찾아본거에 의하면 암호화는 절대로 독자적인 방법으로 만들지 말고
남들이 많이 쓰는 안전하다고 입증된 알고리즘을 입증된 라이브러리 써서 적용하라고 함.

본인이 겁나 능력이 출중한게 아니면…

크리에이티브 커먼즈 라이선스 Linsoo 의 저작물인 이 저작물은(는) 크리에이티브 커먼즈 저작자표시-동일조건변경허락 4.0 국제 라이선스 에 따라 이용할 수 있습니다.

“C#에서 AES256으로 암호화 하기”에 대한 4개의 댓글

  1. 심각도 코드 설명 프로젝트 파일 줄 비표시 오류(Suppression) 상태
    오류 CS1729 'Rfc2898DeriveBytes'에는 인수를 4개 사용하는 생성자가 포함되어 있지 않습니다. ConsoleApp1 C:\Users\82105\Documents\Visual Studio 2017\Projects\ConsoleApp1\ConsoleApp1\AES256.cs 36 활성

    이렇게 나오는데 이거 왜이럴까요 …. ? ㅠㅠ

    1. 타깃 프레임웍 버전이 4.72 미만이라 그렇습니다.

      https://docs.microsoft.com/ko-kr/dotnet/api/system.security.cryptography.rfc2898derivebytes.-ctor?view=netframework-4.7.2#System_Security_Cryptography_Rfc2898DeriveBytes__ctor_System_String_System_Byte___System_Int32_System_Security_Cryptography_HashAlgorithmName_

      4.71까지는 4개 쓰는 생성자가 없었네요.
      타깃 프레임웍 버전을 올리거나 아니면 아랫버전에 맞게 수정해 쓰셔야 할듯 싶습니다.

댓글 남기기

이메일은 공개되지 않습니다.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.