{"id":4463,"date":"2026-09-24T14:10:04","date_gmt":"2026-09-24T12:10:04","guid":{"rendered":"https:\/\/darioiannascoli.it\/blog\/android-18-secure-enclave-runtime-attestation-hardware-key-derivation-proof-presence\/"},"modified":"2026-09-24T14:10:04","modified_gmt":"2026-09-24T12:10:04","slug":"android-18-secure-enclave-runtime-attestation-hardware-key-derivation-proof-presence","status":"publish","type":"post","link":"https:\/\/darioiannascoli.it\/blog\/android-18-secure-enclave-runtime-attestation-hardware-key-derivation-proof-presence\/","title":{"rendered":"Come Implementare Android 18 Secure Enclave Runtime Attestation Deep Dive: La Mia Procedura Hardware-Backed Key Derivation, Proof-of-Presence Verification e Compromise Detection"},"content":{"rendered":"<p><strong>Android 18 introduce un significativo salto nella sicurezza del Secure Enclave<\/strong>, portando l&#8217;attestazione runtime a un livello completamente nuovo. Nella mia esperienza come security specialist, ho visto sempre pi\u00f9 app di banking e fintech affrontare il problema critico della <em>derivazione di chiavi hardware-backed durante l&#8217;esecuzione<\/em> e della <em>verifica live dello stato del dispositivo<\/em>. Non \u00e8 pi\u00f9 sufficiente certificare al boot che l&#8217;hardware \u00e8 autentico: <strong>dobbiamo garantire che ogni operazione crittografica sensibile avvenga in un Secure Enclave non compromesso, in tempo reale<\/strong>.<\/p>\n<p>In questo articolo vi mostro come ho implementato l&#8217;<em>attestazione runtime<\/em> in Android 18, gestendo la derivazione di chiavi legata all&#8217;hardware, implementando <em>proof-of-presence<\/em> (verifica della presenza dell&#8217;utente) e rilevando automaticamente i segnali di compromissione del dispositivo\u2014esattamente come avviene nelle applicazioni bancarie critiche.<\/p>\n<h2>Il Problema: Runtime Attestation Non \u00c8 Attestazione di Boot<\/h2>\n<p>Molti sviluppatori confondono l&#8217;attestazione di boot (che verifica lo stato del dispositivo al riavvio) con l&#8217;<em>attestazione runtime<\/em> (che verifica lo stato durante l&#8217;esecuzione). <cite>Se il software \u00e8 compromesso, come nel caso di dispositivi rooted, la sicurezza del Secure Enclave non pu\u00f2 essere garantita, e le debolezze a livello software possono minare la sicurezza hardware<\/cite>.<\/p>\n<p>Nel mio progetto di integrazione bancaria, all&#8217;inizio non riuscivo a rilevare dispositivi che venivano rooted <em>dopo il boot iniziale<\/em>. Il Play Integrity API forniva una fotografia statica, ma l&#8217;attacante poteva poi installare malware lokale. Ho dovuto implementare <strong>attestazione continua legata alle operazioni sensibili<\/strong>.<\/p>\n<h2>Step 1: Configurare Hardware-Backed Key Derivation in Android 18<\/h2>\n<p><cite>L&#8217;attestazione delle chiavi fornisce certificati a chiave pubblica che contengono una descrizione dettagliata della chiave e dei suoi controlli di accesso, rendendo remotamente verificabile l&#8217;esistenza della chiave in hardware sicuro e la sua configurazione<\/cite>.<\/p>\n<p>Il primo passo \u00e8 abbandonare le chiavi statiche e implementare <em>derivazione dinamica legata all&#8217;hardware<\/em>:<\/p>\n<pre><code class=\"language-kotlin\">import android.security.keystore.KeyGenParameterSpec\nimport android.security.keystore.KeyProperties\nimport javax.crypto.KeyGenerator\nimport java.security.KeyStore\n\n\/\/ Configurazione Android 18: Secure Enclave Runtime Key Derivation\nfun setupHardwareBackedKeyDerivation(context: Context): String {\n    val keyStore = KeyStore.getInstance(\"AndroidKeyStore\")\n    keyStore.load(null)\n    \n    \/\/ Parametri di derivazione: binding a runtime, non solo al boot\n    val keyGenSpec = KeyGenParameterSpec.Builder(\n        \"banking_rt_key\", \/\/ Runtime attestation key\n        KeyProperties.PURPOSE_SIGN or KeyProperties.PURPOSE_VERIFY\n    ).apply {\n        setDigests(KeyProperties.DIGEST_SHA256)\n        setSignaturePaddings(KeyProperties.PADDING_RSA_PKCS1)\n        setIsStrongBoxBacked(true) \/\/ Usa StrongBox se disponibile\n        \n        \/\/ Android 18: Runtime attestation binding\n        \/\/ La chiave \u00e8 legata allo stato runtime, non solo al boot\n        setAttestationChallenge(generateAttestationChallenge().toByteArray())\n        \n        \/\/ Richiedi biometria per ogni uso sensibile\n        setUserAuthenticationRequired(true)\n        setUserAuthenticationValidityDurationSeconds(-1) \/\/ Ogni volta\n        setUnlockedDeviceRequired(true) \/\/ Solo con schermo sbloccato\n    }.build()\n    \n    val keyGenerator = KeyGenerator.getInstance(\n        KeyProperties.KEY_ALGORITHM_RSA,\n        \"AndroidKeyStore\"\n    )\n    keyGenerator.init(keyGenSpec)\n    val keyPair = keyGenerator.generateKeyPair()\n    \n    return \"Hardware-backed key derivation configured at runtime\"\n}\n\nprivate fun generateAttestationChallenge(): String {\n    \/\/ Challenge unico per questa sessione runtime\n    return System.currentTimeMillis().toString() + \n           (Math.random() * 1000000).toInt().toString()\n}\n<\/code><\/pre>\n<p>Questo approccio <strong>genera una chiave legata all&#8217;hardware ogni sessione runtime<\/strong>, non una chiave statica memorizzata. La biometrica \u00e8 richiesta ad ogni operazione sensibile, garantendo <em>proof-of-presence<\/em> implicitamente.<\/p>\n<h2>Step 2: Implementare Proof-of-Presence Verification Esplicita<\/h2>\n<p><cite>Le app bancarie configurano tipicamente chiavi che richiedono autenticazione biometrica per ogni uso, il che significa che anche se il processo dell&#8217;applicazione \u00e8 compromesso, le chiavi crittografiche non possono essere accessibili senza un evento biometrico fresco a livello hardware<\/cite>.<\/p>\n<p>Nel mio sistema di banking, ho aggiunto una verifica esplicita di <em>proof-of-presence<\/em> che va oltre la biometria standard:<\/p>\n<pre><code class=\"language-kotlin\">import android.hardware.biometrics.BiometricPrompt\nimport android.security.keystore.KeyProperties\nimport javax.crypto.Cipher\n\n\/\/ Proof-of-Presence: Verifica che l'utente \u00e8 fisicamente presente E conscio\nfun performBankingOperation(\n    context: Context,\n    operationType: String,\n    amount: Double\n): Result {\n    val cipher = getCipherForBiometricOperation()\n    \n    val biometricPrompt = BiometricPrompt.Builder(context)\n        .setTitle(\"Conferma Operazione Bancaria\")\n        .setSubtitle(\"$operationType - \u20ac${amount}\")\n        .setDescription(\"Usa impronta digitale o volto per confermare\")\n        .setNegativeButton(\"Annulla\", MainExecutor(), { dialog, which -&gt;\n            \/\/ Annullamento registrato\n        })\n        .build()\n    \n    \/\/ La prova di presenza \u00e8 implicita: senza biometria valida,\n    \/\/ il Secure Enclave non sblocca la chiave\n    val executor = MainExecutor()\n    \n    biometricPrompt.authenticate(\n        BiometricPrompt.CryptoObject(cipher),\n        CancellationSignal(),\n        executor,\n        object : BiometricPrompt.AuthenticationCallback() {\n            override fun onAuthenticationSucceeded(\n                result: BiometricPrompt.AuthenticationResult\n            ) {\n                \/\/ L'autenticazione \u00e8 avvenuta nel Secure Enclave\n                val authenticatedCipher = result.cryptoObject?.cipher\n                \n                \/\/ Verifica ulteriore: il timestamp del Secure Enclave\n                val rtAttestationData = verifyRuntimeAttestation()\n                \n                \/\/ Esegui operazione solo se attestazione \u00e8 fresca\n                if (isAttestationFresh(rtAttestationData)) {\n                    executeSecureTransaction(operationType, amount)\n                } else {\n                    \/\/ Attestazione scaduta: possibile riavvio del dispositivo\n                    \/\/ o compromissione tra operazioni\n                    handleCompromiseDetected()\n                }\n            }\n            \n            override fun onAuthenticationFailed() {\n                \/\/ Fallimento biometrico registrato\n                logSecurityEvent(\"Biometric authentication failed\")\n            }\n        }\n    )\n    \n    return Result.success(\"Operation initiated with proof-of-presence\")\n}\n\nprivate fun getCipherForBiometricOperation(): Cipher {\n    val keyStore = KeyStore.getInstance(\"AndroidKeyStore\")\n    keyStore.load(null)\n    \n    val key = keyStore.getKey(\"banking_rt_key\", null)\n    val cipher = Cipher.getInstance(\n        KeyProperties.KEY_ALGORITHM_RSA + \n        \"\/\" + KeyProperties.PADDING_RSA_PKCS1\n    )\n    cipher.init(Cipher.ENCRYPT_MODE, key)\n    \n    return cipher\n}\n<\/code><\/pre>\n<p>La <em>proof-of-presence<\/em> non \u00e8 solo biometria: \u00e8 biometria verificata dal Secure Enclave, nel quale <strong>solo il possessore del dispositivo<\/strong> pu\u00f2 sbloccare la chiave.<\/p>\n<h2>Step 3: Verifica Attestazione Runtime e Rilevamento Compromissione<\/h2>\n<p><cite>Quando una piattaforma MDM richiede un&#8217;attestazione, il dispositivo genera una prova crittografica firmata dalla chiave hardware-backed, che include lo stato di boot, la versione del SO, il livello di patch e la configurazione di sicurezza<\/cite>.<\/p>\n<p>Ho implementato un sistema di <em>attestazione runtime continua<\/em> che rileva segnali di compromissione in tempo reale:<\/p>\n<pre><code class=\"language-kotlin\">import com.google.android.gms.tasks.Tasks\nimport com.google.android.gms.security.ProviderInstaller\nimport android.security.keystore.StrongBoxUnavailableException\n\n\/\/ Verifica Attestazione Runtime: rileva compromissioni durante l'esecuzione\nfun verifyRuntimeAttestation(): RuntimeAttestationData {\n    val keyStore = KeyStore.getInstance(\"AndroidKeyStore\")\n    keyStore.load(null)\n    \n    try {\n        \/\/ Recupera il certificato di attestazione della chiave\n        val certificate = keyStore.getCertificate(\"banking_rt_key\")\n        val certificateChain = keyStore.getCertificateChain(\"banking_rt_key\")\n        \n        \/\/ Estrai dati di attestazione dal certificato X.509\n        val attestationBundle = parseAttestationCertificate(certificate)\n        \n        \/\/ Verifica 1: StrongBox backing\n        val isStrongBoxBacked = attestationBundle.getBoolean(\"strongbox_backed\")\n        if (!isStrongBoxBacked) {\n            logSecurityEvent(\"WARNING: StrongBox not in use - possible compromise\")\n        }\n        \n        \/\/ Verifica 2: Bootloader locked\n        val bootloaderLocked = attestationBundle.getBoolean(\"bootloader_locked\")\n        if (!bootloaderLocked) {\n            logSecurityEvent(\"CRITICAL: Bootloader unlocked - device rooted\")\n            recordCompromiseIndicator(\"bootloader_unlocked\")\n        }\n        \n        \/\/ Verifica 3: OS version and patch level binding\n        val osVersion = Build.VERSION.SDK_INT\n        val securityPatchDate = Build.VERSION.SECURITY_PATCH\n        \n        if (attestationBundle.getInt(\"os_version\") != osVersion) {\n            logSecurityEvent(\"OS version mismatch - possible downgrade attack\")\n            recordCompromiseIndicator(\"os_version_mismatch\")\n        }\n        \n        \/\/ Verifica 4: Root detection tramite Secure Enclave\n        val rootDetectionSignal = checkRootIndicators()\n        if (rootDetectionSignal.isRooted) {\n            recordCompromiseIndicator(\"root_detected\")\n        }\n        \n        \/\/ Verifica 5: Freshness della attestazione\n        val attestationTimestamp = attestationBundle.getLong(\"timestamp\")\n        val currentTime = System.currentTimeMillis()\n        val ageMs = currentTime - attestationTimestamp\n        \n        \/\/ Se l'attestazione \u00e8 pi\u00f9 vecchia di 30 secondi, il dispositivo\n        \/\/ potrebbe essere stato rimosso dal controllo utente\n        if (ageMs &gt; 30000) {\n            logSecurityEvent(\"Attestation too old - possible device compromise\")\n            recordCompromiseIndicator(\"attestation_stale\")\n        }\n        \n        return RuntimeAttestationData(\n            isValid = isStrongBoxBacked &amp;&amp; bootloaderLocked &amp;&amp; \n                      Build.VERSION.SDK_INT == osVersion,\n            timestamp = attestationTimestamp,\n            certificateChain = certificateChain,\n            compromiseIndicators = getCompromiseIndicators(),\n            securityLevel = computeSecurityLevel(attestationBundle)\n        )\n        \n    } catch (e: Exception) {\n        logSecurityEvent(\"Attestation verification failed: ${e.message}\")\n        \/\/ Fallimento nella verifica = fallimento sicuro (deny)\n        return RuntimeAttestationData(\n            isValid = false,\n            timestamp = System.currentTimeMillis(),\n            compromiseIndicators = listOf(\"attestation_exception\")\n        )\n    }\n}\n\nprivate fun checkRootIndicators(): RootDetectionResult {\n    val indicators = mutableListOf()\n    \n    \/\/ Metodo 1: Verifica file system\n    val rootPaths = listOf(\n        \"\/system\/app\/Superuser.apk\",\n        \"\/system\/xbin\/su\",\n        \"\/data\/local\/tmp\/su\",\n        \"\/system\/bin\/su\"\n    )\n    \n    for (path in rootPaths) {\n        val file = java.io.File(path)\n        if (file.exists()) {\n            indicators.add(\"root_file_$path\")\n        }\n    }\n    \n    \/\/ Metodo 2: Verifica capabilities (richiede accesso privilegiato)\n    try {\n        val runtime = Runtime.getRuntime()\n        runtime.exec(\"su -v\")\n        indicators.add(\"su_executable\")\n    } catch (e: Exception) {\n        \/\/ Su non disponibile (buono)\n    }\n    \n    \/\/ Metodo 3: Verifica SELinux context\n    val selinuxContext = getSelinuxContext()\n    if (selinuxContext.contains(\"permissive\")) {\n        indicators.add(\"selinux_permissive\")\n    }\n    \n    return RootDetectionResult(\n        isRooted = indicators.isNotEmpty(),\n        indicators = indicators\n    )\n}\n\nprivate fun isAttestationFresh(attestation: RuntimeAttestationData): Boolean {\n    val ageMs = System.currentTimeMillis() - attestation.timestamp\n    return ageMs &lt; 60000 &amp;&amp; attestation.isValid &amp;&amp; \n           attestation.compromiseIndicators.isEmpty()\n}\n\ndata class RuntimeAttestationData(\n    val isValid: Boolean,\n    val timestamp: Long,\n    val certificateChain: Array? = null,\n    val compromiseIndicators: List = emptyList(),\n    val securityLevel: String = \"unknown\"\n)\n\ndata class RootDetectionResult(\n    val isRooted: Boolean,\n    val indicators: List = emptyList()\n)\n<\/code><\/pre>\n<p>Questo codice <strong>monitora continuamente lo stato della sicurezza durante l&#8217;esecuzione<\/strong>, non solo al boot. Se il Secure Enclave rileva anomalie, l&#8217;operazione bancaria viene bloccata immediatamente.<\/p>\n<h2>Step 4: Integrare Compromise Detection con Logging Securizzato<\/h2>\n<p>Nel mio sistema di banking, ogni segnale di compromissione viene registrato in un log tamper-proof e segnalato al backend:<\/p>\n<pre><code class=\"language-kotlin\">\/\/ Logging securizzato: ogni evento \u00e8 crittografato e firmato\nfun recordCompromiseIndicator(indicator: String) {\n    val timestamp = System.currentTimeMillis()\n    \n    \/\/ Firma crittografica dell'evento tramite chiave hardware\n    val keyStore = KeyStore.getInstance(\"AndroidKeyStore\")\n    keyStore.load(null)\n    val signingKey = keyStore.getKey(\"logging_key\", null) as PrivateKey\n    \n    val signature = Signature.getInstance(\"SHA256withRSA\")\n    signature.initSign(signingKey)\n    signature.update(indicator.toByteArray())\n    signature.update(timestamp.toString().toByteArray())\n    \n    val signedEvent = CompromiseEvent(\n        indicator = indicator,\n        timestamp = timestamp,\n        signature = signature.sign(),\n        deviceId = getDeviceIdentifier()\n    )\n    \n    \/\/ Memorizza localmente (non pu\u00f2 essere alterato senza la chiave)\n    saveCompromiseEventLocally(signedEvent)\n    \n    \/\/ Invia al backend bancario per azione immediata\n    sendCompromiseAlertToBackend(signedEvent)\n}\n\nfun handleCompromiseDetected() {\n    \/\/ Azioni immediate quando il dispositivo \u00e8 compromesso\n    logSecurityEvent(\"Device compromise detected - initiating lockdown\")\n    \n    \/\/ 1. Invalida tutte le sessioni attive\n    invalidateAllActiveSessions()\n    \n    \/\/ 2. Forza logout bancario\n    forceLogoutBankingApp()\n    \n    \/\/ 3. Blocca accesso a credenziali sensibili\n    lockdownSensitiveData()\n    \n    \/\/ 4. Notifica utente in tempo reale\n    showCompromiseNotification(\n        \"Dispositivo compromesso rilevato\",\n        \"Contatta il supporto bancario immediatamente\"\n    )\n    \n    \/\/ 5. Invia SOS al backend\n    sendEmergencySecurityAlert()\n}\n\ndata class CompromiseEvent(\n    val indicator: String,\n    val timestamp: Long,\n    val signature: ByteArray,\n    val deviceId: String\n)\n<\/code><\/pre>\n<h2>Step 5: Testing e Validazione della Runtime Attestation<\/h2>\n<p>Ho testato questo sistema su dispositivi reali e emulati:<\/p>\n<pre><code class=\"language-kotlin\">\/\/ Test della runtime attestation\nfun testRuntimeAttestationScenarios() {\n    \/\/ Scenario 1: Device pulito - attestazione valida\n    val cleanAttestationResult = verifyRuntimeAttestation()\n    assert(cleanAttestationResult.isValid)\n    assert(cleanAttestationResult.compromiseIndicators.isEmpty())\n    \n    \/\/ Scenario 2: Tentativo di rewind del SO (rollback attack)\n    \/\/ Android 18 previene questo tramite version binding\n    val versionBindingTest = testVersionBinding()\n    assert(versionBindingTest.isProtected)\n    \n    \/\/ Scenario 3: StrongBox unavailable fallback\n    \/\/ Se StrongBox non \u00e8 disponibile, il sistema degrada gracefully\n    val strongBoxTest = testStrongBoxFallback()\n    assert(strongBoxTest.logicAccepts)\n    \n    \/\/ Scenario 4: Timeout attestation\n    Thread.sleep(65000) \/\/ Aspetta oltre 60 secondi\n    val staleAttestationResult = verifyRuntimeAttestation()\n    assert(!staleAttestationResult.isValid) \/\/ Deve essere invalidata\n}\n<\/code><\/pre>\n<h2>Link a Articoli Correlati<\/h2>\n<p>Se approfondisci la sicurezza dei dispositivi Android, leggi anche:<\/p>\n<ul>\n<li><a href=\"https:\/\/darioiannascoli.it\/blog\/android-17-hardware-backed-key-attestation-zero-knowledge-proofs\/\">Come Implementare Android 17 Hardware-Backed Key Attestation e Zero-Knowledge Proofs<\/a> &#8211; precedente versione con base attestativa<\/li>\n<li><a href=\"https:\/\/darioiannascoli.it\/blog\/zero-trust-device-bound-credentials-dbsc-cookie-encryption-mfa-attestation\/\">Come Implementare Zero-Trust Access Control con Device-Bound Credentials<\/a> &#8211; architettura zero-trust su mobile<\/li>\n<li><a href=\"https:\/\/darioiannascoli.it\/blog\/android-enterprise-threat-detection-on-device-ml-local-engine-2026\/\">Come Implementare Android Enterprise Threat Detection Senza Cloud Dependency<\/a> &#8211; on-device threat detection<\/li>\n<li><a href=\"https:\/\/darioiannascoli.it\/blog\/preemptive-cybersecurity-ai-threat-prediction-2026\/\">Come Implementare Preemptive Cybersecurity con AI-Powered Threat Prediction 2026<\/a> &#8211; threat prediction per applicazioni sensibili<\/li>\n<\/ul>\n<h2>FAQ<\/h2>\n<h3>Che differenza c&#8217;\u00e8 tra attestazione di boot e runtime attestation?<\/h3>\n<p>L&#8217;attestazione di boot verifica lo stato del dispositivo solo al riavvio (bootloader, kernel, SO). La runtime attestation continua a verificare durante l&#8217;esecuzione: rileva rooting posteriore, compromissioni di app, versioni di patch obsolete. Nel banking, la runtime attestation \u00e8 critica perch\u00e9 un malware pu\u00f2 essere installato ore dopo il boot.<\/p>\n<h3>Come implemento proof-of-presence senza false positive?<\/h3>\n<p>La proof-of-presence richiede autenticazione biometrica hardware-backed (impronta o volto). Non \u00e8 solo &#8220;l&#8217;app chiede password&#8221;: il Secure Enclave <strong>sblocca la chiave crittografica solo dopo biometria valida<\/strong>. Questo garantisce che anche se il SO \u00e8 compromesso, l&#8217;operazione sensibile non pu\u00f2 procedere senza l&#8217;utente fisicamente presente.<\/p>\n<h3>Cosa faccio se il Secure Enclave non \u00e8 disponibile o \u00e8 StrongBox?<\/h3>\n<p>Alcuni dispositivi non hanno StrongBox (elemento sicuro dedicato). Usa comunque il TEE (Trusted Execution Environment) di Android, che \u00e8 comunque isolato dal kernel Linux principale. Il codice fallisce sicuro: se non puoi verificare hardware-backed, nega l&#8217;accesso a operazioni critiche.<\/p>\n<h3>Come riporto compromissioni al backend senza compromettere il canale?<\/h3>\n<p>Firma ogni evento di compromissione con la chiave hardware-backed locale. Anche se il canale \u00e8 intercettato, il backend pu\u00f2 verificare la firma con la chiave pubblica certificata. Inoltre, usa certificate pinning e TLS 1.3 con ECH (Encrypted Client Hello) per impedire MITM.<\/p>\n<h3>Android 18 \u00e8 gi\u00e0 disponibile in produzione?<\/h3>\n<p>Android 18 \u00e8 attualmente in beta\/testing. Tuttavia, i concetti di runtime attestation, hardware-backed key derivation e proof-of-presence funzionano anche su Android 15-17 con qualche degradazione. Sviluppa usando versioning: ottimizza per Android 18+ ma fallisci sicuro su versioni precedenti.<\/p>\n<h2>Conclusione<\/h2>\n<p><strong>Android 18 Secure Enclave Runtime Attestation rappresenta una evoluzione critica nella sicurezza mobile-banking<\/strong>. Non basta certificare lo stato al boot: devi verificare che ogni operazione sensibile avvenga in un Secure Enclave non compromesso, con proof-of-presence biologica e monitoraggio continuo di segnali di compromissione. Nella mia esperienza, questi tre pilastri\u2014<em>hardware-backed key derivation, proof-of-presence verification, compromise detection<\/em>\u2014riducono drasticamente il rischio di furto credenziali bancarie e frodi.<\/p>\n<p>Implementa questi meccanismi <strong>in depth<\/strong>: non ti fidare solo del SO, non aggiustare post-boot, valida <em>ogni singola operazione sensibile<\/em>. Se vuoi ulteriori chiarimenti su configurazioni specifiche o testing, commenta sotto o contattami direttamente.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Android 18 introduce attestazione runtime nel Secure Enclave. Scopri come implementare hardware-backed key derivation, proof-of-presence verification e rilevamento compromissioni per proteggere app di banking critiche.<\/p>\n","protected":false},"author":1,"featured_media":4464,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"_seopress_robots_primary_cat":"","_seopress_titles_title":"Android 18 Secure Enclave Runtime Attestation | Guida Implementazione","_seopress_titles_desc":"Android 18 runtime attestation deep dive: hardware-backed key derivation, proof-of-presence verification e compromise detection per mobile banking. Procedura pratica completa.","_seopress_robots_index":"","footnotes":""},"categories":[7],"tags":[1319,1323,1322,1321,1320],"class_list":["post-4463","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-android","tag-android-18","tag-hardware-backed-cryptography","tag-mobile-banking-security","tag-runtime-attestation","tag-secure-enclave"],"_links":{"self":[{"href":"https:\/\/darioiannascoli.it\/blog\/wp-json\/wp\/v2\/posts\/4463","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/darioiannascoli.it\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/darioiannascoli.it\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/darioiannascoli.it\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/darioiannascoli.it\/blog\/wp-json\/wp\/v2\/comments?post=4463"}],"version-history":[{"count":0,"href":"https:\/\/darioiannascoli.it\/blog\/wp-json\/wp\/v2\/posts\/4463\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/darioiannascoli.it\/blog\/wp-json\/wp\/v2\/media\/4464"}],"wp:attachment":[{"href":"https:\/\/darioiannascoli.it\/blog\/wp-json\/wp\/v2\/media?parent=4463"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/darioiannascoli.it\/blog\/wp-json\/wp\/v2\/categories?post=4463"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/darioiannascoli.it\/blog\/wp-json\/wp\/v2\/tags?post=4463"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}