Certificate Pinning: cos’è, meccanismo e metodi di fissaggio

Autore: IT Sectr Pubblicato: 2026-03-09 Tempo di lettura: 8 min

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 — tecnica in cui un’applicazione si fida solo di un certificato con un’impronta nota in anticipo, ignorando l’intera catena CA
  • Public Key Pinning — alternativa che fissa solo la chiave pubblica, semplificando la rotazione al cambio del certificato
  • HPKP (HTTP Public Key Pinning) — standard obsoleto a livello di intestazioni HTTP, non raccomandato per nuovi progetti
  • Backup pins — impronte di riserva che garantiscono la continuità della connessione quando il certificato principale viene modificato o scade
  • Implementazione su iOS tramite SecTrustEvaluate, su Android tramite CertificatePinner in OkHttp o TrustManager

Cos’è il Certificate Pinning?

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.

Storia ed evoluzione del Certificate Pinning

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.

Come funziona il Certificate Pinning?

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.

kotlin
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.

Certificate Pinning vs Public Key Pinning

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.

CriterioCertificate PinningPublic Key Pinning
Oggetto di fissaggioCertificato X.509 completoChiave pubblica RSA/ECDSA
RotazioneRichiede aggiornamento ad ogni nuova emissioneNon cambia al rinnovo del certificato con la stessa chiave
SicurezzaLegame di massima precisioneMeno sensibile ai dettagli
FlessibilitàBassa — i certificati cambiano ogni 1–2 anniAlta — le chiavi possono durare 5–10 anni
RaccomandazionePer sistemi critici con aggiornamenti controllatiPer 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.

Trust On First Use (TOFU)

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.

Implementazione su iOS e Android

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.

swift
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.

TrustManager personalizzato per Android

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.

Errori nell’implementazione del Certificate Pinning

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.

  • Ignorare la catena di certificati — verificare solo il certificato foglia senza considerare le CA intermedie, interrompendo la connessione durante la rotazione
  • Date hardcoded — date di scadenza dei certificati codificate che non cambiano dopo gli aggiornamenti
  • Nessun monitoraggio — assenza di avvisi sugli errori di Certificate Pinning, con problemi scoperti solo dagli utenti
  • TOFU senza convalida — utilizzo di Trust On First Use senza verifica aggiuntiva, consentendo al primo attacco MITM di fissare un certificato fraudolento

Domande Frequenti

Qual è la differenza tra Certificate Pinning e SSL Pinning?

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.

Come archiviare in modo sicuro le impronte dei certificati in un’applicazione?

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.

Con quale frequenza cambiare le impronte fissate?

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.

Si può disabilitare il Certificate Pinning per il debug?

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.

Cosa fare se un certificato viene compromesso?

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

  • Certificate Pinning — fissaggio di un certificato fidato o della sua chiave pubblica per proteggersi da attacchi MITM tramite CA fraudolente
  • Due approcci — certificate pinning (rigoroso, al certificato) e public key pinning (flessibile, alla chiave pubblica)
  • Backup pins obbligatori — almeno 2 impronte per garantire la continuità durante la rotazione dei certificati
  • OkHttp CertificatePinner — metodo di implementazione standard su Android con supporto per più pin
  • URLSessionDelegate — metodo principale su iOS con verifica manuale di SecTrust e hash SHA-256
  • Errori comuni — mancanza di backup pins, archiviazione senza offuscamento, confusione delle configurazioni debug/release
  • Raccomandazione — usare public key pinning per la maggior parte dei progetti e Certificate Pinning solo per i sistemi critici

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.

Discuti il progetto

Leggi anche