File size: 6,581 Bytes
5cf429e
eb48225
5cf429e
 
eb48225
5cf429e
eb48225
 
7191e6a
eb48225
 
7191e6a
eb48225
5cf429e
eb48225
 
5cf429e
eb48225
 
94b8a3f
eb48225
5cf429e
 
eb48225
5cf429e
 
d1be50a
5cf429e
 
d1be50a
 
 
5cf429e
 
 
 
eb48225
5cf429e
7191e6a
eb48225
 
 
 
 
 
 
 
 
94b8a3f
eb48225
 
 
 
5cf429e
eb48225
 
 
 
 
 
 
 
 
 
 
 
 
5cf429e
eb48225
94b8a3f
eb48225
 
94b8a3f
eb48225
 
 
94b8a3f
5cf429e
eb48225
 
 
 
5cf429e
eb48225
94b8a3f
eb48225
7191e6a
 
eb48225
5cf429e
d1be50a
eb48225
 
 
1db56f0
eb48225
1db56f0
eb48225
 
1db56f0
d1be50a
7191e6a
5cf429e
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import gradio as gr
import core # Import all our local logic

# ==============================================================================
#  GRADIO UI HELPER FUNCTIONS
# ==============================================================================
def creator_wrapper(public_key: str, secret_data: str):
    """UI wrapper for the image creation logic."""
    try:
        created_image = core.create_encrypted_image(secret_data, public_key)
        return created_image, f"βœ… Success! Image created. You can now go to the 'Send KeyLock' tab to test it."
    except Exception as e:
        return None, f"❌ Error: {e}"

def decoder_wrapper(image: gr.Image, private_key: str):
    """UI wrapper for the image decryption logic."""
    try:
        decrypted_data = core.decode_data_from_image(image, private_key)
        return decrypted_data, "βœ… Success! Data decrypted from image."
    except Exception as e:
        return None, f"❌ Error: {e}"

# ==============================================================================
#  GRADIO DASHBOARD INTERFACE
# ==============================================================================
theme = gr.themes.Base(
    primary_hue=gr.themes.colors.blue, secondary_hue=gr.themes.colors.sky, neutral_hue=gr.themes.colors.slate,
    font=(gr.themes.GoogleFont("Inter"), "system-ui", "sans-serif"),
).set(
    body_background_fill="#F1F5F9", panel_background_fill="white", block_background_fill="white",
    block_border_width="1px", block_shadow="*shadow_drop_lg",
    button_primary_background_fill="*primary_600", button_primary_background_fill_hover="*primary_700",
)

with gr.Blocks(theme=theme, title="KeyLock Operations Dashboard") as demo:
    gr.Markdown("# πŸ”‘ KeyLock Operations Dashboard")
    gr.Markdown("A self-contained demonstration of the entire KeyLock workflow: Key Generation, Image Creation, and Decryption.")

    with gr.Tabs() as tabs:
        with gr.TabItem("β‘  Generate Keys", id=0):
            gr.Markdown("## Step 1: Create a Secure Key Pair")
            gr.Markdown(
                """
                Every secure system starts with a key pair. This consists of a **Public Key** and a **Private Key**.
                - **Public Key πŸ”‘:** You can share this with anyone. It's used only for *encrypting* data. In a real system, you would add this key to a server's configuration file (like an `endpoints.json`) so that clients know how to encrypt data for it.
                - **Private Key πŸ”:** This must be kept **absolutely secret**. It is the only key that can *decrypt* data encrypted with its corresponding public key. In a real system, this would be stored as a secure environment variable or secret on the server.
                """
            )
            with gr.Row(variant="panel"):
                with gr.Column(scale=1):
                    gr.Markdown("### Your New Keys")
                    gen_keys_button = gr.Button("Generate New 2048-bit Key Pair", variant="secondary")
                    gr.Markdown("⬇️ **Copy these keys for the next steps!**")
                with gr.Column(scale=2):
                     with gr.Row():
                        output_public_key = gr.Textbox(lines=11, label="Generated Public Key (For Creator)", interactive=False, show_copy_button=True)
                        output_private_key = gr.Textbox(lines=11, label="Generated Private Key (For Decoder)", interactive=False, show_copy_button=True)

        with gr.TabItem("β‘‘ Create KeyLock", id=1):
            gr.Markdown("## Step 2: Create an Encrypted Auth Image")
            gr.Markdown("This tool acts as the **Auth Creator**. It takes your secret data and uses the **Public Key** from Step 1 to encrypt it into a new PNG image. This simulates a user preparing their credentials to send to a secure service.")
            with gr.Row(variant="panel"):
                with gr.Column(scale=1):
                    gr.Markdown("### Configuration")
                    creator_pubkey_input = gr.Textbox(lines=8, label="Paste the Public Key Here", placeholder="Copy the public key generated in Step 1...")
                    creator_secret_input = gr.Textbox(lines=5, label="Secret Data to Encrypt", placeholder="API_KEY: sk-123...\nUSER: demo-user")
                    creator_button = gr.Button("✨ Create Auth Image", variant="primary")
                with gr.Column(scale=1):
                    gr.Markdown("### Output")
                    creator_status = gr.Textbox(label="Status", interactive=False, lines=2)
                    # format="png" is the key to ensuring the download button creates a proper PNG file.
                    creator_image_output = gr.Image(label="Generated Encrypted Image", type="pil", show_download_button=True, format="png", show_share_button=False)

        with gr.TabItem("β‘’ Send KeyLock", id=2):
            gr.Markdown("## Step 3: Decrypt the Image (Client Simulation)")
            gr.Markdown("This tool acts as the **Client** sending the image to a secure **Server**. To prove it can decrypt the data, the 'Server' needs the corresponding **Private Key** from Step 1. In a real application, you would only send the image; the server would already have its private key.")
            with gr.Row(variant="panel"):
                with gr.Column(scale=1):
                    gr.Markdown("### Input")
                    client_image_input = gr.Image(type="pil", label="Upload or Drag Encrypted Image Here", sources=["upload", "clipboard"])
                    client_private_key_input = gr.Textbox(lines=8, label="Paste the Private Key Here", placeholder="Copy the private key generated in Step 1...")
                    client_button = gr.Button("πŸ”“ Decrypt Image", variant="primary")
                with gr.Column(scale=1):
                    gr.Markdown("### Decrypted Data")
                    client_status = gr.Textbox(label="Status", interactive=False, lines=2)
                    client_json_output = gr.JSON(label="Result from 'Server'")

    # --- Wire up the component logic ---
    gen_keys_button.click(fn=core.generate_rsa_keys, inputs=None, outputs=[output_private_key, output_public_key])
    
    creator_button.click(
        fn=creator_wrapper,
        inputs=[creator_pubkey_input, creator_secret_input],
        outputs=[creator_image_output, creator_status]
    )
    
    client_button.click(
        fn=decoder_wrapper,
        inputs=[client_image_input, client_private_key_input],
        outputs=[client_json_output, client_status]
    )

if __name__ == "__main__":
    demo.launch()