암호화 방식 - AES256, Base64, URL Encoding Decoding

서버 네트워크 통신 시 유출된 Token을 확인하고, 암호화된 Token을 복호화하여 평문화된 파라미터 값을 추출 후 파라미터 값을 임의로 수정하여 생성한 Token 값으로 새로운 정보가 취득 가능한지 확인하는 과정에서 암호화 방식에 대한 의미를 파악함

 

Cipher Method

AES256

AES-256은 고급 암호화 표준(Advanced Encryption Standard)의 일종으로, 256비트 키를 사용하는 대칭 키 암호화 알고리즘입니다. AES-256은 데이터를 인코딩(암호화)하여 보호하며, 이 데이터를 디코딩(복호화)하려면 같은 256비트 키가 필요합니다.

AES-256 인코딩(암호화): 평문(Plaintext)을 256비트 대칭 키를 사용하여 암호화된 암호문(Ciphertext)으로 변환합니다. AES-256은 여러 암호화 모드를 지원하며, CBC(Cipher Block Chaining)와 같은 모드를 사용하면 보안을 강화할 수 있습니다.

AES-256 디코딩(복호화): 암호화된 암호문을 원래의 평문으로 복원하는 과정입니다. 이 과정에서도 암호화에 사용된 동일한 256비트 키가 필요합니다. 디코딩이 성공적으로 이루어지려면 암호화 시 사용된 모드와 키가 정확히 일치해야 합니다.

 

Base64

Base64 인코딩은 바이너리 데이터를 텍스트 형식으로 변환하는 방법입니다. 이 과정은 3바이트(24비트) 데이터를 4개의 6비트 청크로 나누어 각 청크를 0~63 사이의 숫자로 변환하고, 이 숫자를 해당하는 ASCII 문자로 변환합니다. Base64는 일반적으로 이메일 첨부 파일이나 URL 매개변수, JSON Web Token(JWT) 등에서 바이너리 데이터를 안전하게 전송하기 위해 사용됩니다.

Base64 디코딩은 인코딩된 데이터를 다시 원래의 바이너리 형식으로 변환하는 과정입니다. 4개의 Base64 문자로 인코딩된 데이터를 3바이트의 원래 바이너리 데이터로 변환합니다.

 

URL 암호화

URL 인코딩(또는 퍼센트 인코딩)은 URL에 포함될 수 없는 문자(예: 공백, 슬래시, 콜론 등)를 안전하게 전송하기 위해 특수 문자를 % 뒤에 해당 문자의 ASCII 값(16진수 형식)으로 대체하는 방법입니다. 예를 들어, 공백 문자는 %20으로 인코딩됩니다.

URL 디코딩은 이와 반대로 인코딩된 URL을 다시 원래의 텍스트 형식으로 복원하는 과정입니다. 예를 들어, %20을 공백 문자로 변환합니다.

 

URL 파라미터 값을 보호하거나 인코딩 하는 방법

일반적인 처리 순서 : AES256 암호화 → Base64 인코딩 → URL 인코딩

 

AES256 암호화

  • AES256 암호화는 데이터의 기밀성을 보장하기 위해 사용됩니다. 보통 민감한 정보를 보호하기 위해 적용되며, 암호화된 데이터를 전송할 때 사용됩니다.

Base64 인코딩

  • Base64 인코딩은 바이너리 데이터를 텍스트로 변환하여 URL이나 JSON 등의 텍스트 기반 형식에서 사용할 수 있도록 합니다. Base64는 바이너리 데이터를 안전하게 텍스트로 표현할 때 유용합니다.

URL 인코딩

  • URL 인코딩은 URL에 포함될 수 없는 문자(예: 공백, 특수 문자)를 안전하게 포함하기 위해 사용됩니다. URL 파라미터에 사용되는 값들이 특수 문자를 포함하고 있다면, 먼저 URL 인코딩을 적용합니다.

 

AES256 암호화 복호화 코드(by python)

import tkinter as tk
from tkinter import messagebox
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import base64
import urllib.parse

# AES256 키와 IV 준비
key = b''  # 256비트 키
iv = b''  # 128비트 IV

def encrypt():
    plaintext = entry_plaintext.get()
    if not plaintext:
        messagebox.showwarning("Input Error", "Please enter text to encrypt.")
        return
    cipher = AES.new(key, AES.MODE_CBC, iv)
    ciphertext = cipher.encrypt(pad(plaintext.encode(), AES.block_size))
    ciphertext_encoded = base64.b64encode(ciphertext)
    ciphertext_url_encoded = urllib.parse.quote(ciphertext_encoded)
    entry_ciphertext.delete(0, tk.END)
    entry_ciphertext.insert(0, ciphertext_url_encoded)

def decrypt():
    ciphertext_url_encoded = entry_ciphertext.get()
    if not ciphertext_url_encoded:
        messagebox.showwarning("Input Error", "Please enter text to decrypt.")
        return
    try:
        ciphertext_decoded = base64.b64decode(urllib.parse.unquote(ciphertext_url_encoded))
        cipher = AES.new(key, AES.MODE_CBC, iv)
        plaintext = unpad(cipher.decrypt(ciphertext_decoded), AES.block_size)
        entry_plaintext.delete(0, tk.END)
        entry_plaintext.insert(0, plaintext.decode('utf-8'))
    except (ValueError, KeyError) as e:
        messagebox.showerror("Decryption Error", str(e))

# GUI 설정
root = tk.Tk()
root.title("AES256 Encrypt/Decrypt Tool")

tk.Label(root, text="Plaintext:").grid(row=0, column=0, padx=10, pady=10)
entry_plaintext = tk.Entry(root, width=100)
entry_plaintext.grid(row=0, column=1, padx=10, pady=10)

tk.Label(root, text="Ciphertext:").grid(row=1, column=0, padx=10, pady=10)
entry_ciphertext = tk.Entry(root, width=100)
entry_ciphertext.grid(row=1, column=1, padx=10, pady=10)

tk.Button(root, text="Encrypt", command=encrypt).grid(row=2, column=0, padx=10, pady=10)
tk.Button(root, text="Decrypt", command=decrypt).grid(row=2, column=1, padx=10, pady=10)

root.mainloop()