string-AES / app.py
danhtran2mind's picture
Update app.py
f1687a9 verified
raw
history blame
4.15 kB
import secrets
import string
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
from Crypto.Util.Padding import pad, unpad
from Crypto.Hash import SHA256
import base64
import gradio as gr
def generate_random_key(length=32):
"""Generate a random key with digits, uppercase, lowercase, and special characters."""
characters = string.ascii_lowercase + string.ascii_uppercase + string.digits + string.punctuation
key = (
secrets.choice(string.ascii_lowercase) +
secrets.choice(string.ascii_uppercase) +
secrets.choice(string.digits) +
secrets.choice(string.punctuation)
)
key += ''.join(secrets.choice(characters) for _ in range(length - 4))
key_list = list(key)
secrets.SystemRandom().shuffle(key_list)
return ''.join(key_list)
def derive_key(custom_key, key_size):
"""Derive a key of specified size (128, 192, or 256 bits) from a custom string using SHA-256."""
hasher = SHA256.new()
hasher.update(custom_key.encode('utf-8'))
full_hash = hasher.digest()
# Convert key_size to integer before division
return full_hash[:int(key_size) // 8]
def encrypt_string(plain_text, key, key_size):
"""Encrypt a string using AES in CBC mode with specified key size."""
try:
if not plain_text:
return "Error: Please provide text to encrypt."
if not key:
return "Error: Please provide a key."
derived_key = derive_key(key, key_size)
plain_text_bytes = plain_text.encode('utf-8')
iv = get_random_bytes(AES.block_size)
cipher = AES.new(derived_key, AES.MODE_CBC, iv)
padded_text = pad(plain_text_bytes, AES.block_size)
cipher_text = cipher.encrypt(padded_text)
return base64.b64encode(iv + cipher_text).decode('utf-8')
except Exception as e:
return f"Encryption error: {str(e)}"
def decrypt_string(encrypted_text, key, key_size):
"""Decrypt a string using AES in CBC mode with specified key size."""
try:
if not encrypted_text:
return "Error: Please provide encrypted text."
if not key:
return "Error: Please provide a key."
derived_key = derive_key(key, key_size)
raw = base64.b64decode(encrypted_text)
iv = raw[:AES.block_size]
cipher_text = raw[AES.block_size:]
cipher = AES.new(derived_key, AES.MODE_CBC, iv)
padded_text = cipher.decrypt(cipher_text)
return unpad(padded_text, AES.block_size).decode('utf-8')
except Exception as e:
return f"Decryption error: {str(e)}"
def generate_and_display_key():
"""Generate and return a random key."""
return generate_random_key()
# Gradio interface
with gr.Blocks() as demo:
gr.Markdown("# AES Encryption/Decryption App")
gr.Markdown("Encrypt or decrypt text using AES (128, 192, or 256-bit keys).")
with gr.Row():
key_size = gr.Radio(
choices=["128", "192", "256"],
label="AES Key Size (bits)",
value="256"
)
with gr.Row():
custom_key = gr.Textbox(
label="Custom Key",
placeholder="Enter your key or generate one",
lines=1
)
generate_key_btn = gr.Button("Generate Random Key")
with gr.Row():
input_text = gr.Textbox(
label="Input Text",
placeholder="Enter text to encrypt",
lines=3
)
with gr.Row():
encrypt_btn = gr.Button("Encrypt")
decrypt_btn = gr.Button("Decrypt")
output_text = gr.Textbox(
label="Output",
placeholder="Result will appear here",
lines=3,
interactive=False
)
# Event handlers
generate_key_btn.click(
fn=generate_and_display_key,
outputs=custom_key
)
encrypt_btn.click(
fn=encrypt_string,
inputs=[input_text, custom_key, key_size],
outputs=output_text
)
decrypt_btn.click(
fn=decrypt_string,
inputs=[input_text, custom_key, key_size],
outputs=output_text
)
# Launch the app
demo.launch()