Application/C# (WinForm)

[C# (WinForm)] 암호화 및 복호화 (AES)

devsalix 2025. 7. 30. 12:10
728x90

1. 참조 및 전역 변수

using System.Security.Cryptography;
using System.Text;

string m_strKey = "Sample Cryptography Key";

 

 

2. 암호화

private string EncryptStringAES(string plainText, string keyString)
{
    byte[] szDatas = Encoding.UTF8.GetBytes(keyString); // 키를 바이트 배열로 변환
    byte[] key = new byte[32];

    Array.Copy(Encoding.UTF8.GetBytes("12345678901234567890123456789012"), key, key.Length); // key 초기화

    if (szDatas.Length > key.Length)
    {
        Array.Copy(szDatas, key, key.Length);
    }
    else
    {
        Array.Copy(szDatas, key, szDatas.Length);
    }

    using (Aes aesAlg = Aes.Create())
    {
        aesAlg.Key = key;
        aesAlg.Mode = CipherMode.CBC; // CBC 모드 사용 (일반적)
        aesAlg.Padding = PaddingMode.PKCS7; // PKCS7 패딩 사용

        // IV (Initialization Vector)는 매번 새롭게 생성되어야 합니다.
        // IV는 암호화된 데이터와 함께 저장되어야 복호화 시 사용할 수 있습니다.
        aesAlg.GenerateIV();
        byte[] iv = aesAlg.IV;

        ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

        using (MemoryStream msEncrypt = new MemoryStream())
        {
            // IV를 먼저 스트림에 씁니다. (복호화 시 필요)
            msEncrypt.Write(iv, 0, iv.Length);

            using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
            {
                using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                {
                    swEncrypt.Write(plainText);
                }
            }
            // 암호화된 바이트 배열과 IV를 Base64 문자열로 반환
            return Convert.ToBase64String(msEncrypt.ToArray());
        }
    }
}

 

 

3. 복호화

private string DecryptStringAES(string cipherText, string keyString)
{
    byte[] szDatas = Encoding.UTF8.GetBytes(keyString); // 키를 바이트 배열로 변환
    byte[] fullCipher = Convert.FromBase64String(cipherText); // Base64 문자열을 바이트 배열로 변환
    byte[] key = new byte[32];

    Array.Copy(Encoding.UTF8.GetBytes("12345678901234567890123456789012"), key, key.Length); // key 초기화

    if (szDatas.Length > key.Length)
    {
        Array.Copy(szDatas, key, key.Length);
    }
    else
    {
        Array.Copy(szDatas, key, szDatas.Length);
    }

    using (Aes aesAlg = Aes.Create())
    {
        aesAlg.Key = key;
        aesAlg.Mode = CipherMode.CBC;
        aesAlg.Padding = PaddingMode.PKCS7;

        // 암호화된 데이터에서 IV를 추출합니다.
        // IV는 암호화된 데이터의 맨 앞에 저장되어 있다고 가정합니다.
        byte[] iv = new byte[aesAlg.BlockSize / 8]; // BlockSize는 비트 단위이므로 8로 나누어 바이트 단위로 변환
        Array.Copy(fullCipher, 0, iv, 0, iv.Length);
        aesAlg.IV = iv;

        ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);

        using (MemoryStream msDecrypt = new MemoryStream())
        {
            // IV 이후의 실제 암호화된 데이터만 CryptoStream에 전달합니다.
            using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Write))
            {
                csDecrypt.Write(fullCipher, iv.Length, fullCipher.Length - iv.Length);
                csDecrypt.FlushFinalBlock(); // 패딩을 제거하고 최종 블록 처리

                // 복호화된 바이트를 문자열로 변환
                return Encoding.UTF8.GetString(msDecrypt.ToArray());
            }
        }
    }
}

 

 

주의사항
  • 전역 변수로 설정된  Key는 하드 코딩 및 상수로 설정할 경우 유출될 수 있습니다 (리버싱)

 


제 글이 도움이 되셨다면 댓글 & 공감 부탁드려요 😀

 

 
728x90
반응형