This shows you the differences between two versions of the page.
|
ss:laboratoare:07 [2025/02/26 00:33] jan.vaduva |
ss:laboratoare:07 [2026/04/20 16:55] (current) ciprian.popescu0411 |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ====== Laborator 7: Secure Boot și Autentificarea Codului pentru Aplicații Mobile ====== | + | ====== Laborator 7: Securizarea aplicației web pentru gestionarea imaginilor ====== |
| - | ===== Obiective ===== | + | În cadrul acestui laborator ne vom axa pe implementarea securității **Mutual TLS (mTLS)** pentru comunicația MQTT din cadrul aplicației web. |
| - | * Înțelegerea conceptelor de **Secure Boot** și verificarea integrității codului în aplicațiile mobile | + | |
| - | * Implementarea unui mecanism de **verificare a integrității aplicației** pentru a detecta modificări neautorizate | + | |
| - | * Asigurarea protecției împotriva **atacurilor de repackaging** (modificarea și redistribuirea aplicației) | + | |
| - | * Implementarea **firmware authentication** și securizarea procesului de actualizare a aplicației | + | |
| - | * Prevenirea **încărcării codului malițios** și protejarea comunicațiilor dintre aplicație și server | + | |
| - | ===== Cerințe tehnologice ===== | + | ===== Ce este mTLS? ===== |
| - | * **Platforme mobile**: Android (Java/Kotlin), iOS (Swift) | + | |
| - | * **Mecanisme de protecție**: Play Integrity API (Android), App Attest API (iOS) | + | |
| - | * **Semnarea aplicației**: APK Signing v3 (Android), Code Signing (iOS) | + | |
| - | * **Securizarea update-urilor**: Firebase App Distribution, App Store Connect, criptare firmware pentru OTA | + | |
| - | * **Tehnologii criptografice**: RSA/ECDSA pentru verificarea integrității codului | + | |
| - | * **Mecanisme de protecție anti-tampering**: Obfuscation, Root/Jailbreak detection | + | |
| - | ===== Funcționalități ===== | + | **Mutual TLS** (mTLS) este un mecanism de autentificare bidirecțională în care: |
| + | - **Serverul se autentifică** față de client (TLS standard) | ||
| + | - **Clientul se autentifică** față de server (autentificare mutuală/bidirecțională) | ||
| - | ==== 1. Implementarea Secure Boot pentru aplicația mobilă ==== | + | Acest lucru asigură că: |
| - | * Semnarea digitală a aplicației pentru prevenirea modificărilor neautorizate | + | * Datele sunt criptate în tranzit |
| - | * Verificarea integrității codului la rulare folosind checksums și hashing | + | * Doar dispozitivele autorizate se pot conecta la broker |
| - | * Detectarea încercărilor de modificare a aplicației (anti-repackaging) | + | * Atacurile de tip man-in-the-middle sunt prevenite |
| - | ==== 2. Protejarea firmware-ului și a update-urilor aplicației ==== | + | ===== Fișiere de modificat ===== |
| - | * Semnarea și criptarea actualizărilor pentru a preveni atacurile de tip man-in-the-middle | + | |
| - | * Implementarea verificării criptografice înainte de instalarea unui update | + | |
| - | * Utilizarea unui canal securizat pentru descărcarea actualizărilor (TLS, certificate valide) | + | |
| - | ==== 3. Prevenirea atacurilor de manipulare și încărcare de cod malițios ==== | + | ^ Fișier ^ Scop ^ Modificări Necesare ^ |
| - | * Detectarea aplicațiilor care rulează pe dispozitive rootate sau jailbreak | + | | ''broker/mosquitto.conf'' | Configurare Broker | Activarea listener-ului securizat pe portul 8883 | |
| - | * Implementarea protecției împotriva atacurilor prin încărcarea dinamică de cod (Dynamic Code Loading) | + | | ''docker-compose.yml'' | Configurare Servicii | Montarea secretelor și expunerea porturilor | |
| - | * Monitorizarea și raportarea încercărilor de modificare a aplicației în timp real | + | | ''server/main.go'' | Backend | Implementarea configurației TLS pentru clientul MQTT | |
| + | | ''scripts/send_image.py'' | Script Python | Configurarea contextului SSL/TLS | | ||
| - | ===== Evaluare ===== | + | ===== Cerințe preliminare ===== |
| - | * Implementarea mecanismului de verificare a integrității codului (30%) | + | |
| - | * Protecția procesului de update și verificarea firmware-ului (40%) | + | |
| - | * Detectarea și prevenirea atacurilor asupra aplicației (30%) | + | |
| - | ===== Resurse suplimentare ===== | + | * OpenSSL instalat (''brew install openssl'' pe macOS) |
| - | * [https://developer.android.com/guide/app-bundle/app-signing Android APK Signing] | + | * Acces la directorul ''secrets/'' din rădăcina proiectului |
| - | * [https://developer.apple.com/documentation/security/app_attest Apple App Attest] | + | |
| - | * [https://developer.android.com/google/play/integrity Play Integrity API] | + | |
| - | * [https://owasp.org/www-project-mobile-security-testing-guide/ OWASP Mobile Security Testing Guide] | + | |
| + | ===== Pasul 1: Generarea certificatelor ===== | ||
| + | |||
| + | ==== 1.1 Crearea Autorității de Certificare (CA) ==== | ||
| + | |||
| + | <code bash> | ||
| + | mkdir -p secrets | ||
| + | cd secrets | ||
| + | |||
| + | # Generarea cheii private a CA | ||
| + | openssl genrsa -out ca.key 4096 | ||
| + | |||
| + | # Generarea certificatului CA (valabil 10 ani) | ||
| + | openssl req -new -x509 -days 3650 -key ca.key -out ca.crt \ | ||
| + | -subj "/C=RO/ST=Romania/L=Bucharest/O=SS-Web/OU=Security/CN=SS-Web-CA" | ||
| + | </code> | ||
| + | |||
| + | ==== 1.2 Crearea certificatului de server (pentru brokerul Mosquitto) ==== | ||
| + | |||
| + | <code bash> | ||
| + | # Generarea cheii private a serverului | ||
| + | openssl genrsa -out server.key 2048 | ||
| + | |||
| + | # Generarea cererii de semnare a certificatului de server (CSR) | ||
| + | openssl req -new -key server.key -out server.csr \ | ||
| + | -subj "/C=RO/ST=Romania/L=Bucharest/O=SS-Web/OU=Broker/CN=broker" | ||
| + | |||
| + | # Semnarea certificatului de server cu CA (valabil 1 an) | ||
| + | openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key \ | ||
| + | -CAcreateserial -out server.crt | ||
| + | |||
| + | # Curățare CSR | ||
| + | rm server.csr | ||
| + | </code> | ||
| + | |||
| + | ==== 1.3 Crearea certificatului de client (pentru API-ul Go și scripturile Python) ==== | ||
| + | |||
| + | <code bash> | ||
| + | # Generarea cheii private a clientului | ||
| + | openssl genrsa -out web.key 2048 | ||
| + | |||
| + | # Generarea cererii de semnare a certificatului de client (CSR) | ||
| + | openssl req -new -key web.key -out web.csr \ | ||
| + | -subj "/C=RO/ST=Romania/L=Bucharest/O=SS-Web/OU=WebClient/CN=web" | ||
| + | |||
| + | # Semnarea certificatului de client cu CA (valabil 1 an) | ||
| + | openssl x509 -req -days 365 -in web.csr -CA ca.crt -CAkey ca.key \ | ||
| + | -CAcreateserial -out web.crt | ||
| + | |||
| + | # Curățare CSR | ||
| + | rm web.csr | ||
| + | </code> | ||
| + | |||
| + | ==== 1.4 Verificarea certificatelor ==== | ||
| + | |||
| + | <code bash> | ||
| + | # Verificarea certificatului CA | ||
| + | openssl x509 -in ca.crt -text -noout | ||
| + | |||
| + | # Verificarea certificatului de server | ||
| + | openssl verify -CAfile ca.crt server.crt | ||
| + | |||
| + | # Verificarea certificatului de client | ||
| + | openssl verify -CAfile ca.crt web.crt | ||
| + | </code> | ||
| + | |||
| + | ===== Pasul 2: Configurarea brokerului Mosquitto ===== | ||
| + | |||
| + | Editați ''broker/mosquitto.conf'' pentru a adăuga listener-ul securizat: | ||
| + | |||
| + | <file bash mosquitto.conf> | ||
| + | # MQTT simplu (doar pentru dezvoltare - dezactivați în producție) | ||
| + | listener 1883 | ||
| + | allow_anonymous true | ||
| + | |||
| + | # MQTT securizat cu mTLS | ||
| + | listener 8883 | ||
| + | cafile /run/secrets/ca.crt | ||
| + | certfile /run/secrets/server.crt | ||
| + | keyfile /run/secrets/server.key | ||
| + | require_certificate true | ||
| + | use_subject_as_username true | ||
| + | allow_anonymous true | ||
| + | |||
| + | # Logare | ||
| + | log_type all | ||
| + | connection_messages true | ||
| + | log_timestamp true | ||
| + | </file> | ||
| + | |||
| + | **Explicarea setărilor cheie:** | ||
| + | * ''cafile'': Certificatul CA pentru verificarea certificatelor clienților | ||
| + | * ''certfile/keyfile'': Certificatul propriu al serverului și cheia privată | ||
| + | * ''require_certificate true'': **Activează mTLS** - clienții trebuie să prezinte un certificat valid | ||
| + | * ''use_subject_as_username true'': Folosește CN-ul certificatului ca nume de utilizator MQTT | ||
| + | |||
| + | ===== Pasul 3: Configurarea Docker Compose ===== | ||
| + | |||
| + | Actualizați ''docker-compose.yml'' pentru a monta secretele: | ||
| + | |||
| + | <file yaml docker-compose.yml> | ||
| + | services: | ||
| + | go-api: | ||
| + | # ... alte configurări ... | ||
| + | secrets: | ||
| + | - ca.crt | ||
| + | - web.crt | ||
| + | - web.key | ||
| + | |||
| + | broker: | ||
| + | # ... alte configurări ... | ||
| + | ports: | ||
| + | - "8883:8883" # MQTT securizat | ||
| + | - "1883:1883" # MQTT simplu (dezactivați în producție) | ||
| + | secrets: | ||
| + | - ca.crt | ||
| + | - server.crt | ||
| + | - server.key | ||
| + | |||
| + | secrets: | ||
| + | ca.crt: | ||
| + | file: ./secrets/ca.crt | ||
| + | web.crt: | ||
| + | file: ./secrets/web.crt | ||
| + | web.key: | ||
| + | file: ./secrets/web.key | ||
| + | server.crt: | ||
| + | file: ./secrets/server.crt | ||
| + | server.key: | ||
| + | file: ./secrets/server.key | ||
| + | </file> | ||
| + | |||
| + | ===== Pasul 4: Configurarea serverului Go ===== | ||
| + | |||
| + | Actualizați ''server/main.go'' pentru a folosi TLS: | ||
| + | |||
| + | <code go> | ||
| + | import ( | ||
| + | "crypto/tls" | ||
| + | "crypto/x509" | ||
| + | "os" | ||
| + | ) | ||
| + | |||
| + | func NewTLSConfig() *tls.Config { | ||
| + | // Încărcarea certificatului CA | ||
| + | certpool := x509.NewCertPool() | ||
| + | pemCerts, err := os.ReadFile("/run/secrets/ca.crt") | ||
| + | if err != nil { | ||
| + | panic(err) | ||
| + | } | ||
| + | certpool.AppendCertsFromPEM(pemCerts) | ||
| + | |||
| + | // Încărcarea certificatului de client | ||
| + | cert, err := tls.LoadX509KeyPair("/run/secrets/web.crt", "/run/secrets/web.key") | ||
| + | if err != nil { | ||
| + | panic(err) | ||
| + | } | ||
| + | |||
| + | return &tls.Config{ | ||
| + | RootCAs: certpool, | ||
| + | ClientCAs: certpool, | ||
| + | Certificates: []tls.Certificate{cert}, | ||
| + | InsecureSkipVerify: false, | ||
| + | } | ||
| + | } | ||
| + | |||
| + | func main() { | ||
| + | // ... configurare MongoDB ... | ||
| + | |||
| + | tlsconfig := NewTLSConfig() | ||
| + | |||
| + | opts := mqtt.NewClientOptions() | ||
| + | opts.AddBroker("ssl://broker:8883") | ||
| + | opts.SetClientID("web").SetTLSConfig(tlsconfig) | ||
| + | |||
| + | // ... restul codului ... | ||
| + | } | ||
| + | </code> | ||
| + | |||
| + | ===== Pasul 5: Configurarea scripturilor Python ===== | ||
| + | |||
| + | Actualizați scripturile Python pentru a folosi TLS: | ||
| + | |||
| + | <code python> | ||
| + | import ssl | ||
| + | |||
| + | # Configurare | ||
| + | PORT = 8883 # Port securizat | ||
| + | |||
| + | # Căile către certificate | ||
| + | SECRETS_DIR = os.path.join(PROJECT_ROOT, "secrets") | ||
| + | CA_CRT = os.path.join(SECRETS_DIR, "ca.crt") | ||
| + | CLIENT_CRT = os.path.join(SECRETS_DIR, "web.crt") | ||
| + | CLIENT_KEY = os.path.join(SECRETS_DIR, "web.key") | ||
| + | |||
| + | # Crearea clientului MQTT | ||
| + | client = mqtt.Client(client_id="device-id") | ||
| + | |||
| + | # Configurarea TLS | ||
| + | client.tls_set( | ||
| + | ca_certs=CA_CRT, | ||
| + | certfile=CLIENT_CRT, | ||
| + | keyfile=CLIENT_KEY, | ||
| + | tls_version=ssl.PROTOCOL_TLSv1_2 | ||
| + | ) | ||
| + | # Omiterea verificării hostname-ului pentru testarea locală | ||
| + | client.tls_insecure_set(True) | ||
| + | |||
| + | # Conectare | ||
| + | client.connect(BROKER, PORT, 60) | ||
| + | </code> | ||
| + | |||
| + | ===== Pasul 6: Testarea conexiunii ===== | ||
| + | |||
| + | * Porniți serviciile: | ||
| + | <code bash> | ||
| + | docker compose up -d | ||
| + | </code> | ||
| + | |||
| + | * Testați conexiunea: | ||
| + | <code bash> | ||
| + | python3 scripts/send_image.py | ||
| + | </code> | ||
| + | |||
| + | * Verificați log-urile brokerului: | ||
| + | <code bash> | ||
| + | docker logs broker | ||
| + | </code> | ||
| + | |||
| + | ===== Depanare ===== | ||
| + | |||
| + | ==== Verificarea certificatului a eșuat ==== | ||
| + | * Asigurați-vă că toate certificatele sunt semnate de același CA | ||
| + | * Verificați datele de expirare: | ||
| + | <code bash> | ||
| + | openssl x509 -in cert.crt -noout -dates | ||
| + | </code> | ||
| + | |||
| + | ==== Conexiune refuzată pe portul 8883 ==== | ||
| + | * Verificați dacă brokerul ascultă: | ||
| + | <code bash> | ||
| + | docker logs broker | ||
| + | </code> | ||
| + | * Verificați setările firewall-ului | ||
| + | |||
| + | ==== Verificarea hostname-ului a eșuat ==== | ||
| + | * Pentru testare locală, folosiți ''client.tls_insecure_set(True)'' | ||
| + | * Pentru producție, asigurați-vă că CN-ul certificatului corespunde hostname-ului | ||
| + | |||
| + | ===== Bune practici de securitate ===== | ||
| + | |||
| + | - **Nu comiteți niciodată certificate în git** — Adăugați ''secrets/'' în ''.gitignore'' | ||
| + | - **Folosiți certificate cu durată scurtă de viață** — Schimbați-le periodic | ||
| + | - **Dezactivați MQTT simplu în producție** — Eliminați listener-ul pe portul 1883 | ||
| + | - **Folosiți dimensiuni mari ale cheilor** — 4096 biți pentru CA, minim 2048 biți pentru server/client | ||
| + | - **Stocați cheile private în siguranță** — Folosiți Docker secrets sau variabile de mediu | ||
| + | |||
| + | ===== Lista de verificare a fișierelor ===== | ||
| + | |||
| + | După implementare, directorul ''secrets/'' ar trebui să conțină: | ||
| + | |||
| + | <code> | ||
| + | secrets/ | ||
| + | ├── ca.crt | ||
| + | ├── ca.key | ||
| + | ├── server.crt | ||
| + | ├── server.key | ||
| + | ├── web.crt | ||
| + | └── web.key | ||
| + | </code> | ||