Update app.py
Browse files
app.py
CHANGED
|
@@ -12,119 +12,93 @@ import gradio as gr
|
|
| 12 |
import os
|
| 13 |
import numpy as np
|
| 14 |
import librosa
|
|
|
|
| 15 |
from resemblyzer import VoiceEncoder
|
| 16 |
from cryptography.fernet import Fernet
|
| 17 |
|
| 18 |
-
# Initialize
|
| 19 |
encoder = VoiceEncoder()
|
| 20 |
|
| 21 |
-
#
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
with open(KEY_FILE, "rb") as key_file:
|
| 25 |
-
encryption_key = key_file.read()
|
| 26 |
-
else:
|
| 27 |
-
encryption_key = Fernet.generate_key()
|
| 28 |
-
with open(KEY_FILE, "wb") as key_file:
|
| 29 |
-
key_file.write(encryption_key)
|
| 30 |
|
| 31 |
-
|
|
|
|
| 32 |
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
def load_audio(file, target_sr=16000):
|
| 38 |
-
"""Loads an audio file and resamples it."""
|
| 39 |
-
audio, sr = librosa.load(file, sr=target_sr)
|
| 40 |
-
return audio
|
| 41 |
-
|
| 42 |
-
def extract_embeddings(user_id, files):
|
| 43 |
-
"""Extracts and stores voice embeddings for a user."""
|
| 44 |
-
embeddings = []
|
| 45 |
-
for file in files:
|
| 46 |
-
audio = load_audio(file.name)
|
| 47 |
-
embedding = encoder.embed_utterance(audio)
|
| 48 |
-
embeddings.append(embedding)
|
| 49 |
-
|
| 50 |
-
np.save(f"embeddings/{user_id}.npy", np.array(embeddings))
|
| 51 |
return f"Voice registered successfully for User ID: {user_id}"
|
| 52 |
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
return False, "No voice data found. Please register first."
|
| 57 |
-
|
| 58 |
-
stored_embeddings = np.load(f"embeddings/{user_id}.npy")
|
| 59 |
-
test_audio = load_audio(test_file.name)
|
| 60 |
-
test_embedding = encoder.embed_utterance(test_audio)
|
| 61 |
-
|
| 62 |
-
similarities = np.dot(stored_embeddings, test_embedding) / (
|
| 63 |
-
np.linalg.norm(stored_embeddings, axis=1) * np.linalg.norm(test_embedding)
|
| 64 |
-
)
|
| 65 |
-
similarity_score = np.mean(similarities)
|
| 66 |
-
|
| 67 |
-
if similarity_score > 0.85:
|
| 68 |
-
return True, f"β
Access Granted! Similarity Score: {similarity_score:.2f}"
|
| 69 |
-
return False, f"β Access Denied! Similarity Score: {similarity_score:.2f}"
|
| 70 |
|
| 71 |
def encrypt_document(user_id, file):
|
| 72 |
-
|
| 73 |
-
|
| 74 |
|
|
|
|
| 75 |
with open(file.name, "rb") as f:
|
| 76 |
encrypted_data = cipher.encrypt(f.read())
|
| 77 |
-
|
| 78 |
-
with open(encrypted_path, "wb") as f:
|
| 79 |
f.write(encrypted_data)
|
|
|
|
|
|
|
| 80 |
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
|
| 98 |
# Gradio UI
|
| 99 |
with gr.Blocks() as app:
|
| 100 |
-
gr.Markdown("
|
| 101 |
-
|
| 102 |
-
# Registration
|
| 103 |
with gr.Row():
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
# Encryption
|
| 111 |
with gr.Row():
|
| 112 |
-
|
| 113 |
-
|
| 114 |
encrypt_button = gr.Button("Encrypt Document")
|
| 115 |
-
|
| 116 |
-
encrypt_button.click(encrypt_document, inputs=[
|
| 117 |
-
|
| 118 |
-
# Authentication & Decryption
|
| 119 |
with gr.Row():
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
encrypted_doc = gr.File(label="Upload Encrypted Document", file_types=[".enc"])
|
| 123 |
decrypt_button = gr.Button("Decrypt Document")
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
app.launch(share=True)
|
| 129 |
-
|
| 130 |
-
|
|
|
|
| 12 |
import os
|
| 13 |
import numpy as np
|
| 14 |
import librosa
|
| 15 |
+
import base64
|
| 16 |
from resemblyzer import VoiceEncoder
|
| 17 |
from cryptography.fernet import Fernet
|
| 18 |
|
| 19 |
+
# Initialize Voice Encoder
|
| 20 |
encoder = VoiceEncoder()
|
| 21 |
|
| 22 |
+
# Directory for storing encrypted documents
|
| 23 |
+
encrypted_dir = "encrypted_docs"
|
| 24 |
+
os.makedirs(encrypted_dir, exist_ok=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 25 |
|
| 26 |
+
# Store user voice embeddings
|
| 27 |
+
db = {}
|
| 28 |
|
| 29 |
+
def register_voice(user_id, files):
|
| 30 |
+
global db
|
| 31 |
+
embeddings = [encoder.embed_utterance(librosa.load(file.name, sr=16000)[0]) for file in files]
|
| 32 |
+
db[user_id] = np.mean(embeddings, axis=0) # Store the mean embedding
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
return f"Voice registered successfully for User ID: {user_id}"
|
| 34 |
|
| 35 |
+
# Generate an encryption key (For simplicity, using a static key. In production, use per-user keys.)
|
| 36 |
+
key = Fernet.generate_key()
|
| 37 |
+
cipher = Fernet(key)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
|
| 39 |
def encrypt_document(user_id, file):
|
| 40 |
+
if user_id not in db:
|
| 41 |
+
return "Error: Register your voice first."
|
| 42 |
|
| 43 |
+
file_path = os.path.join(encrypted_dir, f"{user_id}_{file.name}.enc")
|
| 44 |
with open(file.name, "rb") as f:
|
| 45 |
encrypted_data = cipher.encrypt(f.read())
|
| 46 |
+
with open(file_path, "wb") as f:
|
|
|
|
| 47 |
f.write(encrypted_data)
|
| 48 |
+
|
| 49 |
+
return f"Document encrypted and stored securely as {file_path}"
|
| 50 |
|
| 51 |
+
def authenticate_and_decrypt(user_id, voice_file):
|
| 52 |
+
if user_id not in db:
|
| 53 |
+
return "Error: No registered voice found. Please register your voice first."
|
| 54 |
+
|
| 55 |
+
# Load and process test voice
|
| 56 |
+
test_audio = librosa.load(voice_file.name, sr=16000)[0]
|
| 57 |
+
test_embedding = encoder.embed_utterance(test_audio)
|
| 58 |
+
similarity = np.dot(db[user_id], test_embedding) / (np.linalg.norm(db[user_id]) * np.linalg.norm(test_embedding))
|
| 59 |
+
|
| 60 |
+
if similarity < 0.8:
|
| 61 |
+
return "Authentication failed: Voice does not match."
|
| 62 |
+
|
| 63 |
+
# Locate encrypted file
|
| 64 |
+
user_files = [f for f in os.listdir(encrypted_dir) if f.startswith(user_id)]
|
| 65 |
+
if not user_files:
|
| 66 |
+
return "No encrypted document found for this user."
|
| 67 |
+
|
| 68 |
+
file_path = os.path.join(encrypted_dir, user_files[0])
|
| 69 |
+
with open(file_path, "rb") as f:
|
| 70 |
+
decrypted_data = cipher.decrypt(f.read())
|
| 71 |
+
|
| 72 |
+
# Save decrypted file temporarily
|
| 73 |
+
decrypted_file = "decrypted_document.pdf"
|
| 74 |
+
with open(decrypted_file, "wb") as f:
|
| 75 |
+
f.write(decrypted_data)
|
| 76 |
+
|
| 77 |
+
return decrypted_file # Returning file path for download
|
| 78 |
|
| 79 |
# Gradio UI
|
| 80 |
with gr.Blocks() as app:
|
| 81 |
+
gr.Markdown("# π Secure Document System with Voice Authentication")
|
| 82 |
+
|
|
|
|
| 83 |
with gr.Row():
|
| 84 |
+
user_id_reg = gr.Textbox(label="User ID")
|
| 85 |
+
voice_samples = gr.File(label="Upload Voice Samples", file_types=[".wav"], file_count="multiple")
|
| 86 |
+
reg_button = gr.Button("Register Voice")
|
| 87 |
+
reg_output = gr.Textbox()
|
| 88 |
+
reg_button.click(register_voice, inputs=[user_id_reg, voice_samples], outputs=reg_output)
|
| 89 |
+
|
|
|
|
| 90 |
with gr.Row():
|
| 91 |
+
user_id_enc = gr.Textbox(label="User ID for Encryption")
|
| 92 |
+
document = gr.File(label="Upload Document", file_types=[".pdf"])
|
| 93 |
encrypt_button = gr.Button("Encrypt Document")
|
| 94 |
+
enc_output = gr.Textbox()
|
| 95 |
+
encrypt_button.click(encrypt_document, inputs=[user_id_enc, document], outputs=enc_output)
|
| 96 |
+
|
|
|
|
| 97 |
with gr.Row():
|
| 98 |
+
user_id_auth = gr.Textbox(label="User ID for Authentication")
|
| 99 |
+
auth_voice = gr.File(label="Upload Voice for Authentication", file_types=[".wav"])
|
|
|
|
| 100 |
decrypt_button = gr.Button("Decrypt Document")
|
| 101 |
+
dec_output = gr.File(label="Decrypted Document")
|
| 102 |
+
decrypt_button.click(authenticate_and_decrypt, inputs=[user_id_auth, auth_voice], outputs=dec_output)
|
| 103 |
+
|
|
|
|
| 104 |
app.launch(share=True)
|
|
|
|
|
|