파이썬이 제일 쉬워

[Python] Pycrypto로 AES 개날먹 복호화하기 본문

Python

[Python] Pycrypto로 AES 개날먹 복호화하기

HighBright 2024. 6. 13. 00:48

2024.06.12 - [Python] - [Python] Pycrypto로 AES 개날먹 암호화 하기

 

[Python] Pycrypto로 AES 개날먹 암호화 하기

반갑꼬리~ 오늘은 매우 간단하게 Pycrypto로 AES 암/복호화를 해볼겁니다.정.말.간.단.합.니.다. 10줄 안으로 끝남 ㅇㅇ 먼저 pycrypto를 설치해줍시당pip install pycrypto자 이제 틀부터 잡아봅시다.파일을

highbright.tistory.com

 

※ 전편의 암호화 방식을 이용한 방식만 가능합니당...

 

자 이번엔 전편에 이어서... 암호화를 했으니 복호화를 하는 방법에 대해서 알아봅시다.저번보다 더 간단합니다. 무려.... 8줄컷!!

 
def dec_file(input_file, key):
    with open(input_file, 'rb') as f:
        iv = f.read(16)
        cipher = AES.new(key, AES.MODE_CBC, iv)
        ciphertext = f.read()
    decrypted_data = unpad(cipher.decrypt(ciphertext), AES.block_size)
    with open(input_file[:input_file.rfind('.')], 'wb') as f:
        f.write(decrypted_data)
 

 

설명드갑니다.

 

with open(input_file, 'rb') as f:

    iv = f.read(16) # 초기화 벡터를 읽어옵니다. 전에서 16bytes로 설정했기 때문에 여기도 16bytes입니다   

    cipher = AES.new(key, AES.MODE_CBC, iv) # 새로운 암호화 모듈을 생성해줍니다.   

    ciphertext = f.read() # 나머지 내용을 읽어옵니다.

 

decrypted_data = unpad(cipher.decrypt(ciphertext), AES.block_size)

=> 먼저 cipher.decrypt(ciphertext)로 내용을 복호화하고, 처음에 패딩한 상태로 암호화했으니 다시 패딩을 풀어줍니다.

 

with open(input_file[:input_file.rfind('.')], 'wb') as f:

    f.write(decrypted_data)

=> input_file[:input_file.rfind('.')] 이건 파일 맨 뒤 확장자를 때주는 앱니다.

     test.mp4.aes 파일을 test.mp4 이런 형식으로 다시 저장합니다. 

 

정말 간단하죠?

근데.. 역시 여기서 끝나면 실제로 쓰긴 쉽지않슴다.

그래서 GUI를 조금 뜯어 고쳐봅시다.

 

 
from Crypto.Util.Padding import pad, unpad
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
import tkinter as tk
from tkinter import filedialog, messagebox

def enc_file(input_file, key):
    iv = get_random_bytes(16)
    cipher = AES.new(key, AES.MODE_CBC, iv)
    with open(input_file, 'rb') as f:
        plaintext = f.read()
    padded_plaintext = pad(plaintext, AES.block_size)
    ciphertext = cipher.encrypt(padded_plaintext)
    with open(input_file+".aes", 'wb') as f:
        f.write(iv)
        f.write(ciphertext)

def adjust_key_length(key):
    # 키가 16바이트보다 길 경우 자르기
    if len(key) > 16:
        return key[:16]
    # 키가 16바이트보다 짧을 경우 패딩하기
    elif len(key) < 16:
        padding = b'\0' * (16 - len(key))  # 널(Null)로 패딩
        return key + padding
    # 키가 16바이트일 경우 그대로 반환
    else:
        return key

       
def select_file(): # 파일 주소 받아오기
    file_path = filedialog.askopenfilename()
    file_entry.delete(0, tk.END)
    file_entry.insert(0, file_path)

def start():  
    input_file = file_entry.get()
    key = key_entry.get().encode()
    key = adjust_key_length(key)
    if not input_file or not key:
        messagebox.showerror("에러", "파일이나 키가 비어있습니다. 입력해주세요")
        return
    try:
        if sel.get() == 0: # 암호화가 선택되어 있으면
            enc_file(input_file, key)
            messagebox.showinfo("성공", "암호화 성공")
        elif sel.get() == 1: # 복호화가 선택되어 있으면
            dec_file(input_file, key)
            messagebox.showinfo("성공", "복호화 성공")
    except Exception as e:
        messagebox.showerror("에러", f"에러 발생 : {e}")
       
def check_key_len(*args):
    key_len.configure(text=str(len(key_var.get()))+" Bytes")
   
def dec_file(input_file, key):
    with open(input_file, 'rb') as f:
        iv = f.read(16)
        cipher = AES.new(key, AES.MODE_CBC, iv)
        ciphertext = f.read()
    decrypted_data = unpad(cipher.decrypt(ciphertext), AES.block_size)
    with open(input_file[:input_file.rfind('.')], 'wb') as f:
        f.write(decrypted_data)

root = tk.Tk()
root.title("AES 암복호화")

file_label = tk.Label(root, text="파일 주소 :")
file_label.grid(row=0, column=0, padx=10, pady=10)

file_entry = tk.Entry(root, width=50)
file_entry.grid(row=0, column=1, padx=10, pady=10)

file_button = tk.Button(root, text="파일 선택", command=select_file)
file_button.grid(row=0, column=2, padx=10, pady=10)

key_label = tk.Label(root, text="키 :")
key_label.grid(row=1, column=0, padx=10, pady=10)

key_var = tk.StringVar()
key_var.trace_add('write', check_key_len) # 키 byte 체크
key_entry = tk.Entry(root, width=50, textvariable=key_var)
key_entry.grid(row=1, column=1, padx=10, pady=10)

key_len = tk.Label(root, text="0 Bytes")
key_len.grid(row=1, column=2, padx=10, pady=10)

sel = tk.IntVar() 
type_sel_enc = tk.Radiobutton(root, text="암호화", variable=sel, value=0) # 암호화 선택
type_sel_dec = tk.Radiobutton(root, text="복호화", variable=sel, value=1) # 복호화 선택
type_sel_enc.grid(row=2, column=0, padx=10, pady=10)
type_sel_dec.grid(row=2, column=1, padx=10, pady=10)

start_button = tk.Button(root, text="실행", command=start)
start_button.grid(row=2, column=2, padx=10, pady=20)

root.mainloop()

실행 화면

쟈쟈잔~

 

매우 간단하게 완성했습니다. 총 100줄도 안돼서 완성!

 

그럼 담에 봅시다!

Comments