'복호화'에 해당하는 글 2건

요즘들어 보안에 대한 프로그래밍을 많이 하게 된다.

하래서 한다만 과연 무엇을 위한 보안인지는 모르겠다. 그냥 하는거다.


DB연결자를 구성할때 최소한 서버IP, 사용자정보, 사용자 비밀번호 를 요구한다.

나같은 경우 보통 ini 파일안에 그 정보를 담아두곤 하는데 이 부분에 사용자 비밀번호가 노출돼 보안에 지적될 소지가 있어 암호화 처리하여 ini에 구성한 뒤 복호화 하여 DB Connection을 맺게 구성을 해야 할 것 같다.


그래서 준비해 보았다.



다음과 같은 화면으로 구성해 보았다.


언젠가 쓸 날이 있을거라 본다.


# frmMain.cs

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;


namespace _CS__Generator_Password

{

    public partial class frmMain : Form

    {

        //암호화 복호화 키 8글자 (필히 8자리여야 함)

        WATCrypt m_crypt;


        public frmMain()

        {

            InitializeComponent();

        }


        private void frmMain_Load(object sender, EventArgs e)

        {


        }


        private void btnApply_Click(object sender, EventArgs e)

        {

            if (txtKeyCode.Text.Length != 8)

            {

                MessageBox.Show("Only allows 8-digit");

                return;

            }


            //암호화 복호화 키 8글자 (필히 8자리여야 함)

            m_crypt = new WATCrypt(txtKeyCode.Text);


            txtKeyCode.ReadOnly = true;


        }


        private void btnEncryption_Click(object sender, EventArgs e)

        {

            if (txtKeyCode.ReadOnly == false)

            {

                txtKeyCode.Focus();

                return;

            }


            if (txtEncryption.Text == "")

            {

                txtEncryption.Focus();

                return;

            }


            // 암호화

            txtEncryption_Gene.Text = m_crypt.Encrypt(txtEncryption.Text);

        }


        private void btnDecryption_Click(object sender, EventArgs e)

        {

            if (txtKeyCode.ReadOnly == false)

            {

                return;

            }


            if (txtDecryption.Text == "")

            {

                txtDecryption.Focus();

                return;

            }


            // 복호화

            txtDecryption_Gene.Text = m_crypt.Decrypt(txtDecryption.Text);


        }


    }



}




# WATCrypt.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace _CS__Generator_Password
{

    class WATCrypt
    {

        byte[] Skey = new byte[8];

        public WATCrypt(string strKey)
        {
            Skey = ASCIIEncoding.ASCII.GetBytes(strKey);
        }
        
        public string Encrypt(string p_data)
        {

            if (Skey.Length != 8)
            {
                throw (new Exception("Invalid key. Key length must be 8 byte."));
            }


            DESCryptoServiceProvider rc2 = new DESCryptoServiceProvider();

            rc2.Key = Skey;

            rc2.IV = Skey;

            MemoryStream ms = new MemoryStream();

            CryptoStream cryStream = new CryptoStream(ms, rc2.CreateEncryptor(), CryptoStreamMode.Write);

            byte[] data = Encoding.UTF8.GetBytes(p_data.ToCharArray());
            
            cryStream.Write(data, 0, data.Length);

            cryStream.FlushFinalBlock();
            
            return Convert.ToBase64String(ms.ToArray());

        }
        
        public string Decrypt(string p_data)
        {

            DESCryptoServiceProvider rc2 = new DESCryptoServiceProvider();
            
            rc2.Key = Skey;

            rc2.IV = Skey;
            
            MemoryStream ms = new MemoryStream();

            CryptoStream cryStream = new CryptoStream(ms, rc2.CreateDecryptor(), CryptoStreamMode.Write);

            byte[] data = Convert.FromBase64String(p_data);
            
            cryStream.Write(data, 0, data.Length);

            cryStream.FlushFinalBlock();
            
            return Encoding.UTF8.GetString(ms.GetBuffer());

        }

    }
}



WRITTEN BY
테네시왈츠
항상 겸손하게 항상 새롭게 항상 진실하게

,


using System.Security.Cryptography;
using System.IO;

        private static string EncryptString(string InputText, string Password)
        {

            // Rihndael class를 선언하고, 초기화 합니다
            RijndaelManaged RijndaelCipher = new RijndaelManaged();

            //// 입력받은 문자열을 바이트 배열로 변환
            byte[] PlainText = System.Text.Encoding.Unicode.GetBytes(InputText);

            // 딕셔너리 공격을 대비해서 키를 더더 풀기 어렵게 만들기 위해서
            //// Salt를 사용합니다.
            byte[] Salt = Encoding.ASCII.GetBytes(Password.Length.ToString());

            // PasswordDeriveBytes 클래스를 사용해서 SecretKey를 얻습니다.
            PasswordDeriveBytes SecretKey = new PasswordDeriveBytes(Password, Salt);

            //// Create a encryptor from the existing SecretKey bytes.
            // encryptor 객체를 SecretKey로부터 만듭니다.
            // Secret Key에는 32바이트
            // (Rijndael의 디폴트인 256bit가 바로 32바이트입니다)를 사용하고,
            // Initialization Vector로 16바이트
            // (역시 디폴트인 128비트가 바로 16바이트입니다)를 사용합니다
            ICryptoTransform Encryptor = RijndaelCipher.CreateEncryptor(SecretKey.GetBytes(32), SecretKey.GetBytes(16));

            // 메모리스트림 객체를 선언,초기화
            MemoryStream memoryStream = new MemoryStream();

            // CryptoStream객체를 암호화된 데이터를 쓰기 위한위한 용도로 선언
            CryptoStream cryptoStream = new CryptoStream(memoryStream, Encryptor, CryptoStreamMode.Write);

            // 암호화 프로세스가 진행됩니다.
            cryptoStream.Write(PlainText, 0, PlainText.Length);

            // 암호화 종료
            cryptoStream.FlushFinalBlock();

            // 암호화된 데이터를 바이트 배열로 담습니다.
            byte[] CipherBytes = memoryStream.ToArray();

            //// 스트림 해제
            memoryStream.Close();
            cryptoStream.Close();

            // 암호화된 데이터를 Base64 인코딩된 문자열로 변환합니다.
            string EncryptedData = Convert.ToBase64String(CipherBytes);

            //// 최종 결과를 리턴
            return EncryptedData;

        }

        private static string DecryptString(string InputText, string Password)
        {

            RijndaelManaged RijndaelCipher = new RijndaelManaged();

            byte[] EncryptedData = Convert.FromBase64String(InputText);
            byte[] Salt = Encoding.ASCII.GetBytes(Password.Length.ToString());


            PasswordDeriveBytes SecretKey = new PasswordDeriveBytes(Password, Salt);

            // Decryptor 객체를 만듭니다.
            ICryptoTransform Decryptor = RijndaelCipher.CreateDecryptor(SecretKey.GetBytes(32), SecretKey.GetBytes(16));

            MemoryStream memoryStream = new MemoryStream(EncryptedData);

            // 데이터 읽기(복호화이므로) 용도로 cryptoStream객체를 선언,선언, 초기화
            CryptoStream cryptoStream = new CryptoStream(memoryStream, Decryptor, CryptoStreamMode.Read);

            // 복호화된 데이터를 담을 바이트 배열을 선언합니다.선언합니다.
            // 길이는 알 수 없지만,없지만, 일단 복호화되기 전의 데이터의 길이보다는
            // 길지 않을 것이기 때문에 그 길이로 선언합니다
            byte[] PlainText = new byte[EncryptedData.Length];

            // 복호화 시작
            int DecryptedCount = cryptoStream.Read(PlainText, 0, PlainText.Length);

            memoryStream.Close(); memoryStream.Close();
            cryptoStream.Close();

            // 복호화된 데이터를데이터를 문자열로 바꿉니다.
            string DecryptedData = Encoding.Unicode.GetString(PlainText, 0, DecryptedCount);

            // 최종 결과 리턴리턴
            return DecryptedData;

        }


[출처] http://blog.naver.com/yun4604?Redirect=Log&logNo=10075424101
오타는 좀 많더라... 수정은 해놨지만...

'020. Prigraming > 01. C#' 카테고리의 다른 글

[C#] 사용자 IP 구하기  (0) 2010.06.04
[C#] get과 set에 대하여 알아보자  (0) 2010.06.03
[C#] Convert.ToByte  (0) 2010.05.11
[C#] .net 3.0 LINQ  (0) 2010.05.03
[C#] 프로시저 호출 방법  (0) 2010.04.27

WRITTEN BY
테네시왈츠
항상 겸손하게 항상 새롭게 항상 진실하게

,