Skip to content

Commit 2ab0b11

Browse files
authored
Merge pull request #1272 from J-B-Mugundh/ml-model-security-framework
Added ML Model Protection Framework for Face Authentication
2 parents 8e7a848 + 5160865 commit 2ab0b11

File tree

9 files changed

+620
-0
lines changed

9 files changed

+620
-0
lines changed
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
## Project Overview
2+
3+
This project addresses the security challenges of deploying ML models for face authentication in a browser context. Our goal is to safeguard the ML model from reverse engineering and tampering while ensuring that security measures do not significantly impact the model’s size or degrade the user experience.
4+
5+
## Description
6+
7+
The application provides a proof of concept for face authentication using TensorFlow.js and FaceMesh in a browser environment. It integrates a Trusted Execution Environment (TEE) for secure handling of the ML model, employing AES-256 encryption for data protection and obfuscation techniques to optimize model size and security.
8+
9+
## How It Works
10+
11+
1. **Face Detection**:
12+
- The frontend uses TensorFlow.js and the FaceMesh model to detect faces via the webcam.
13+
- An encrypted message containing the face data is sent to the web server.
14+
15+
2. **Data Handling**:
16+
- The web server forwards the encrypted data to the TEE server for decryption and authentication.
17+
18+
3. **Model Security**:
19+
- The TEE server decrypts the data using AES-256 encryption.
20+
- The model is obfuscated and snapshotting is used to minimize its size and improve load times.
21+
22+
4. **Authentication**:
23+
- Based on the decrypted data, the TEE server checks if the face authentication is successful.
24+
- The result is sent back to the web server and then displayed to the client.
25+
26+
## Technologies, Frameworks, and Tools
27+
28+
- **Frontend**:
29+
- HTML
30+
- JavaScript
31+
- TensorFlow.js
32+
- FaceMesh
33+
34+
- **Backend**:
35+
- Flask
36+
- MongoDB (for potential data storage)
37+
38+
- **Security**:
39+
- AES-256 Encryption
40+
- Trusted Execution Environment (TEE)
41+
- Obfuscation
42+
- Snapshotting
43+
44+
## Unique Selling Points
45+
46+
- **Secure Model Handling**: Utilizes Trusted Execution Environment (TEE) to protect against tampering and reverse engineering.
47+
- **Efficient Encryption**: Employs AES-256 encryption for secure data transmission.
48+
- **Optimized Model Size**: Integrates obfuscation and snapshotting techniques to minimize model size impact.
49+
- **Real-Time Authentication**: Leverages TensorFlow.js and FaceMesh for accurate face detection directly in the browser.
50+
- **Seamless Integration**: Maintains user experience with minimal performance overhead while ensuring robust security.
51+
52+
## Installation
53+
54+
1. **Clone the repository**:
55+
```bash
56+
git clone <repository-url>
57+
cd <repository-name>
58+
```
59+
60+
2. **Install Python dependencies**:
61+
```bash
62+
pip install -r requirements.txt
63+
```
64+
65+
## Running the Application
66+
67+
1. **Start the TEE server**:
68+
```bash
69+
python tee_server.py
70+
```
71+
72+
2. **Start the Web server**:
73+
```bash
74+
python web_server.py
75+
```
76+
77+
3. **Access the application**:
78+
Open a web browser and navigate to `http://localhost:5000`. You will see the registration and login pages.
79+
80+
4. **Test the application**:
81+
- **Register**: Enter a username and click "Register" to save the face image.
82+
- **Login**: Enter the username and click "Login" to authenticate with the captured face image. Successful login will redirect to the home page.
83+
84+
## Troubleshooting
85+
86+
- **Video not appearing**: Ensure that the webcam is properly connected and permissions are granted for the browser to access it.
87+
- **Issues with image capture**: Check the browser console for errors related to the webcam or canvas.
88+
89+
## Acknowledgments
90+
91+
- Thanks to TensorFlow.js and FaceMesh for their face detection capabilities.
369 KB
Loading
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from cryptography.hazmat.primitives.ciphers import algorithms
2+
from cryptography.hazmat.primitives import hashes
3+
from cryptography.hazmat.backends import default_backend
4+
import base64
5+
import os
6+
7+
# Generate a 256-bit (32-byte) AES key
8+
key = os.urandom(32) # AES-256 requires a 32-byte key
9+
iv = os.urandom(16) # AES block size is 16 bytes
10+
11+
# Encode key and IV in Base64 for easy storage in .env
12+
key_b64 = base64.b64encode(key).decode('utf-8')
13+
iv_b64 = base64.b64encode(iv).decode('utf-8')
14+
15+
# Print the results
16+
print(f'AES_KEY={key_b64}')
17+
print(f'AES_IV={iv_b64}')
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Flask
2+
cryptography
3+
python-dotenv
4+
requests
5+
face_recognition
6+
pillow
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
let model;
2+
3+
// Initialize the camera for video feed
4+
async function initializeCamera() {
5+
const video = document.getElementById('video');
6+
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
7+
video.srcObject = stream;
8+
}
9+
10+
// Load the FaceMesh model (for client-side basic processing if needed)
11+
async function initializeModel() {
12+
model = await facemesh.load();
13+
document.getElementById('status').textContent = 'Model loaded, ready for authentication...';
14+
}
15+
16+
// Capture an image from the video feed
17+
function captureImage() {
18+
const video = document.getElementById('video');
19+
const canvas = document.getElementById('canvas');
20+
const context = canvas.getContext('2d');
21+
canvas.width = video.videoWidth;
22+
canvas.height = video.videoHeight;
23+
context.drawImage(video, 0, 0, canvas.width, canvas.height);
24+
return canvas.toDataURL('image/png');
25+
}
26+
27+
// Register a new user with the captured image
28+
async function register() {
29+
const username = document.getElementById('register-username').value;
30+
const image = captureImage();
31+
32+
const response = await fetch('/register', {
33+
method: 'POST',
34+
headers: { 'Content-Type': 'application/json' },
35+
body: JSON.stringify({ username: username, data: image })
36+
});
37+
38+
const result = await response.json();
39+
document.getElementById('status').textContent = result.result || result.error;
40+
}
41+
42+
// Login a user and authenticate their face
43+
async function login() {
44+
const username = document.getElementById('login-username').value;
45+
const image = captureImage();
46+
47+
const response = await fetch('/login', {
48+
method: 'POST',
49+
headers: { 'Content-Type': 'application/json' },
50+
body: JSON.stringify({ username: username, data: image })
51+
});
52+
53+
const result = await response.json();
54+
document.getElementById('status').textContent = result.result || result.error;
55+
56+
if (result.result) {
57+
// Redirect to a dummy home page after successful login
58+
setTimeout(() => {
59+
window.location.href = "/static/home.html";
60+
}, 2000);
61+
}
62+
}
63+
64+
// Toggle between register and login forms
65+
function toggleAuth() {
66+
const registerContainer = document.getElementById('register-container');
67+
const loginContainer = document.getElementById('login-container');
68+
69+
if (registerContainer.classList.contains('auth-hidden')) {
70+
registerContainer.classList.remove('auth-hidden');
71+
loginContainer.classList.add('auth-hidden');
72+
} else {
73+
registerContainer.classList.add('auth-hidden');
74+
loginContainer.classList.remove('auth-hidden');
75+
}
76+
}
77+
78+
// Initialize everything on page load
79+
initializeCamera();
80+
initializeModel();
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Welcome Home</title>
7+
<style>
8+
body {
9+
font-family: Arial, sans-serif;
10+
background: linear-gradient(135deg, #f06, #ff9a9e);
11+
margin: 0;
12+
height: 100vh;
13+
display: flex;
14+
justify-content: center;
15+
align-items: center;
16+
color: #fff;
17+
overflow: hidden;
18+
}
19+
20+
.container {
21+
text-align: center;
22+
max-width: 600px;
23+
padding: 20px;
24+
background: rgba(0, 0, 0, 0.6);
25+
border-radius: 10px;
26+
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
27+
}
28+
29+
h1 {
30+
font-size: 3rem;
31+
margin: 0;
32+
opacity: 0;
33+
animation: fadeIn 2s forwards;
34+
animation-delay: 1s;
35+
}
36+
37+
p {
38+
font-size: 1.2rem;
39+
margin: 20px 0;
40+
opacity: 0;
41+
animation: fadeIn 2s forwards;
42+
animation-delay: 2s;
43+
}
44+
45+
button {
46+
padding: 10px 20px;
47+
font-size: 1rem;
48+
color: #fff;
49+
background-color: #007bff;
50+
border: none;
51+
border-radius: 5px;
52+
cursor: pointer;
53+
transition: background-color 0.3s ease;
54+
opacity: 0;
55+
animation: fadeIn 2s forwards;
56+
animation-delay: 3s;
57+
}
58+
59+
button:hover {
60+
background-color: #0056b3;
61+
}
62+
63+
@keyframes fadeIn {
64+
from {
65+
opacity: 0;
66+
transform: translateY(20px);
67+
}
68+
to {
69+
opacity: 1;
70+
transform: translateY(0);
71+
}
72+
}
73+
</style>
74+
</head>
75+
<body>
76+
<div class="container">
77+
<h1>Welcome Home!</h1>
78+
<p>You have successfully logged in.</p>
79+
<button onclick="window.location.href='/'">Back to Login</button>
80+
</div>
81+
</body>
82+
</html>

0 commit comments

Comments
 (0)