Certificate Pinning è un meccanismo di fissaggio del certificato o della chiave pubblica del server, in cui l’applicazione utilizza un’impronta nota in anticipo per verificare la connessione HTTPS. A differenza della catena di fiducia standard tramite una CA, il pinning garantisce che anche un’autorità di certificazione compromessa non possa emettere un certificato fraudolento per il tuo dominio. Secondo OWASP MSTG (2025), il Certificate Pinning fa parte dell’elenco dei controlli obbligatori per le applicazioni con livello di protezione L2. L’implementazione include l’archiviazione degli hash dei certificati nel codice e la verifica ad ogni richiesta.
Punti Chiave
Certificate Pinning è una tecnica di sicurezza in cui un’applicazione memorizza l’impronta di un certificato fidato e la utilizza come unico criterio per stabilire una connessione HTTPS. Nel modello TLS standard, il client verifica che il certificato del server sia firmato da una CA radice fidata — una delle centinaia di autorità di certificazione preinstallate nel sistema. Il Certificate Pinning sostituisce questa catena con un controllo diretto: il certificato deve corrispondere al campione memorizzato o contenere la chiave pubblica attesa.
Il problema del modello standard è diventato evidente dopo gli incidenti di compromissione delle CA — DigiNotar (2011), Comodo (2011), TrustCor (2022). Se una CA emette un certificato fraudolento per il tuo dominio, il browser o l’applicazione lo accetta come valido. Certificate Pinning previene questo attacco: anche un certificato fraudolento perfettamente firmato verrà rifiutato perché la sua impronta non corrisponde a quella fissata nell’applicazione.
Il termine pinning deriva da pin — “spillo” o “fissatore”: lo sviluppatore fissa un certificato fidato, e qualsiasi deviazione da esso blocca la connessione. Secondo lo studio di Mitre CWE-295, la convalida impropria dei certificati rimane uno dei 10 errori di sicurezza più pericolosi nelle applicazioni mobili, e il Certificate Pinning è un metodo diretto per prevenirlo.
Originariamente, il Certificate Pinning veniva utilizzato nei browser attraverso il meccanismo HPKP (HTTP Public Key Pinning), standardizzato nella RFC 7469. Lo sviluppatore inviava un’intestazione HTTP Public-Key-Pins con gli hash delle chiavi attese, e il browser le memorizzava per un periodo specificato. Tuttavia, HPKP si rivelò pericoloso: un singolo errore di configurazione poteva bloccare un sito per mesi. Nel 2018, Chrome ha interrotto il supporto per HPKP, e lo standard attuale è diventato l’implementazione lato client — all’interno di un’applicazione mobile o di un’estensione del browser.
Il processo di Certificate Pinning comprende tre fasi chiave: calcolo dell’impronta, verifica della connessione e gestione degli errori. Durante la preparazione, lo sviluppatore ottiene l’hash SHA-256 del certificato o della chiave pubblica del server di produzione. Per le applicazioni conformi a GDPR e PCI DSS, è necessario anche fissare le impronte delle CA intermedie nella catena.
Ad ogni richiesta HTTPS, l’applicazione intercetta il callback di autenticazione TLS, estrae il certificato del server e calcola il suo hash SHA-256. Questo hash viene confrontato con l’elenco memorizzato delle impronte fidate. Se viene trovata una corrispondenza — la connessione prosegue. In caso contrario — l’applicazione deve terminare la connessione e segnalare l’errore senza rivelare i dettagli di implementazione all’attaccante.
fun validateCertificate(certificate: X509Certificate,
expectedHash: String): Boolean {
val digest = MessageDigest.getInstance("SHA-256")
val hash = Base64.encodeToString(
digest.digest(certificate.publicKey.getEncoded()),
Base64.DEFAULT
).trim()
return hash == expectedHash
}
La funzione riceve un oggetto X509Certificate dal server e l’hash atteso. Per prima cosa estrae la chiave pubblica del certificato, calcola l’hash SHA-256 e lo codifica in Base64. Il risultato viene confrontato con l’impronta attesa. In produzione, è opportuno aggiungere la verifica contro un array di 2–3 impronte per supportare la rotazione.
Nell’implementare il pinning, bisogna scegliere quale oggetto crittografico fissare. Il Certificate Pinning si lega al certificato X.509 stesso — al suo numero di serie, periodo di validità e all’intera catena. Il Public Key Pinning fissa solo la chiave pubblica all’interno del certificato, ignorando gli altri campi. Questa scelta influisce significativamente sui costi operativi.
| Criterio | Certificate Pinning | Public Key Pinning |
|---|---|---|
| Oggetto di fissaggio | Certificato X.509 completo | Chiave pubblica RSA/ECDSA |
| Rotazione | Richiede aggiornamento ad ogni nuova emissione | Non cambia al rinnovo del certificato con la stessa chiave |
| Sicurezza | Legame di massima precisione | Meno sensibile ai dettagli |
| Flessibilità | Bassa — i certificati cambiano ogni 1–2 anni | Alta — le chiavi possono durare 5–10 anni |
| Raccomandazione | Per sistemi critici con aggiornamenti controllati | Per la maggior parte delle applicazioni mobili e API |
Public Key Pinning è la scelta preferita per la maggior parte dei progetti. Le chiavi pubbliche dei server rimangono generalmente invariate quando si riemette un certificato — l’azienda firma semplicemente la vecchia chiave con un nuovo certificato. Ciò significa che l’applicazione non richiede un aggiornamento dopo un cambio di certificato se la coppia di chiavi non è cambiata. Il Certificate Pinning, invece, è raccomandato per scenari in cui lo sviluppatore controlla completamente sia il server che il codice client, come nelle applicazioni aziendali con un ciclo di aggiornamento rigoroso.
TOFU è una strategia in cui il Certificate Pinning non viene configurato in anticipo, ma ricorda il certificato alla prima connessione al server. Questo approccio è comodo per le applicazioni che non sanno in anticipo a quale server si collegheranno. Lo svantaggio è la vulnerabilità a un attacco iniziale: se la prima connessione viene intercettata, un certificato fraudolento verrà accettato come fidato. TOFU viene utilizzato nelle connessioni SSH e in alcuni protocolli P2P.
Su entrambe le piattaforme, il Certificate Pinning viene implementato intercettando la connessione TLS a livello di stack di rete. Su iOS, viene utilizzato il delegato URLSession o Alamofire ServerTrustManager. Su Android, il metodo preferito è OkHttp CertificatePinner, integrato nei client HTTP più popolari e che supporta la configurazione di più impronte per ogni dominio.
func validate(serverTrust: SecTrust,
pinnedHash: String) -> Bool {
guard let certificates = SecTrustCopyCertificateChain(serverTrust)
as? [SecCertificate] else { return false }
for certificate in certificates {
let data = SecCertificateCopyData(certificate)
var hash = Data(repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
data.withUnsafeBytes {
CC_SHA256($0.baseAddress,
CC_LONG(data.count), &hash)
}
if hash.base64EncodedString() == pinnedHash {
return true
}
}
return false
}
Nella funzione Swift, la catena di certificati viene estratta da serverTrust, viene calcolato un hash SHA-256 per ogni certificato e il risultato viene confrontato con quello atteso. Iterare attraverso tutti i certificati nella catena consente di implementare il pinning a livello di CA intermedia — se un certificato intermedio corrisponde, la connessione viene accettata. Ciò offre flessibilità durante la rotazione dei certificati foglia.
Se l’applicazione non utilizza OkHttp, il Certificate Pinning può essere implementato tramite un X509TrustManager personalizzato. Questo metodo richiede più codice ma offre il controllo completo sul processo di verifica. Il TrustManager sovrascrive il metodo checkServerTrusted, dove lo sviluppatore verifica manualmente i certificati del server e decide se fidarsi. È raccomandato solo per scenari specifici in cui la libreria OkHttp non è disponibile.
L’errore più comune è l’assenza di backup pins. Lo sviluppatore include una singola impronta del certificato e, quando scade, gli utenti perdono la connessione in massa. La configurazione minima accettabile è di due impronte: il certificato corrente e uno di riserva. Idealmente tre: quello corrente, uno di riserva e l’impronta della CA radice come fallback.
Il secondo errore è l’archiviazione dei pins in testo semplice nel codice. Un attaccante con accesso a un APK o IPA può facilmente estrarre e sostituire le impronte. Si raccomanda l’offuscamento degli hash: dividere la stringa in parti, archiviare in risorse crittografate o calcolare in fase di esecuzione. Per Android, ProGuard con offuscamento delle costanti stringa è efficace.
Il terzo errore è il pinning a livello di certificato di sviluppo. I certificati di sviluppo e produzione sono generalmente diversi, ma gli sviluppatori spesso dimenticano di cambiare i pins durante la compilazione di una release. Il risultato è che l’applicazione di produzione non riesce a connettersi al server. La soluzione sono configurazioni di pins separate per debug e release tramite BuildConfig o risorse specifiche del flavor.
Domande Frequenti
SSL Pinning è un termine generale per il legame a un certificato SSL/TLS. Certificate Pinning è un’implementazione specifica che fissa il certificato X.509 stesso, non solo la chiave pubblica. La differenza sta nell’oggetto del legame: certificato vs chiave.
Si raccomanda di archiviare gli hash in risorse con offuscamento tramite ProGuard (Android) o crittografati tramite Keychain (iOS). Evita di archiviare i pins in testo semplice in strings.xml o Info.plist senza crittografia.
Ad ogni cambio di certificato sul server. Si raccomanda di aggiungere una nuova impronta come backup pin 3–6 mesi prima della scadenza di quella corrente e di rimuovere quella vecchia dopo la rotazione. Almeno un backup pin è obbligatorio.
Sì, tramite compilazione condizionale: il pinning è disabilitato nella build di debug e abilitato nella build di release. Usa BuildConfig.DEBUG su Android o #if DEBUG su iOS per commutare. Non farlo mai tramite un flag di runtime accessibile all’utente.
Pubblica immediatamente un aggiornamento dell’applicazione con nuove impronte negli store. Usa un meccanismo di aggiornamento forzato. Se i backup pins includevano l’impronta della CA di riserva, puoi temporaneamente passare a un altro dominio con un certificato diverso.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche