Android 17: como ECH, CT e permissões mudam seu app

Android 17: como ECH, CT e permissões mudam seu app

ECH: o fim do SNI exposto que sua operadora ainda lê hoje

Toda vez que você digita meusite.com no navegador, mesmo com HTTPS, o primeiro pacote da conexão — o TLS ClientHello — viaja em texto claro com o nome do domínio dentro do campo SNI (Server Name Indication). Isso existe porque um mesmo IP pode hospedar dezenas de sites e o servidor precisa saber qual certificado entregar. O problema: operadoras, proxies corporativos e qualquer intermediário no caminho enxergam esse domínio. Não o conteúdo, mas a URL. É o suficiente para montar perfil de consumo, vender dados e bloquear sites por nome.

Segundo o Sapo.pt, o Android 17 generaliza o suporte ao protocolo ECH (Encrypted Client Hello), fechando essa brecha em conjunto com DNS privado. Eu já estava testando isso desde a preview do Android 14 com Cloudflare, mas a maioria dos usuários nunca ativou nada. Agora vem por padrão. Vamos dissecar o impacto real para quem desenvolve.

Como o ECH funciona no handshake TLS

O ECH depende de três peças funcionando juntas:

  1. Resolução DNS encriptada (DoH ou DoT) retornando um registro HTTPS do tipo ech= com a chave pública do ECHConfig.
  2. Cliente que cifra o ClientHello completo usando essa chave, apontando o SNI externo para um “ech” público (ex.: cloudflare-ech.com).
  3. Servidor de borda (geralmente CDN) que decifra o ClientHello interno e repassa ao origin correto.

Se qualquer peça falhar, o handshake cai para TLS 1.2 com SNI exposto. Por isso o ECH só entrega valor real quando o DNS também está encriptado — e é exatamente essa a combinação que o Android 17 ativa.

Testando ECH hoje, antes do rollout oficial

Para verificar se um site já fala ECH via Cloudflare 1.1.1.1:

# consulta o registro HTTPS RR e procura ECHConfig
dig +short HTTPS cloudflare.com @1.1.1.1

# curl com suporte a ECH (BoringSSL/OpenSSL 3.2+)
curl --version | grep -i ech
curl -v --ech true https://cloudflare.com 2>&1 | grep -i "ech\|echConfig"

Se você roda backend próprio e quer habilitar ECH no Nginx com Cloudflare na frente:

# no painel Cloudflare: Network → Enable Encrypted Client Hello
# no origin, garanta que o servidor escuta 443 e aceita SNI virtual:
server {
 listen 443 ssl;
 server_name meusite.com www.meusite.com;

 ssl_certificate /etc/letsencrypt/live/meusite.com/fullchain.pem;
 ssl_certificate_key /etc/letsencrypt/live/meusite.com/privkey.pem;
 ssl_protocols TLSv1.2 TLSv1.3;
}

A configuração real do ECH acontece na borda do CDN. O origin só precisa responder TLS 1.3 corretamente. Na minha experiência, suporte a ECH sem CDN próprio é inviável hoje — você depende de um “ech” confiável.

Permissão de rede local: chega de varredura silenciosa

Antes do Android 17, qualquer app com INTERNET podia varrer 192.168.0.0/16 em segundos. Isso foi usado legitimamente por apps de casting e IoT, mas também virou vetor de fingerprinting e descoberta de dispositivos vulneráveis. A nova versão introduz a permissão NEARBY_WIFI_DEVICES e o atributo localNetworkAccess no manifest.

Se você mantém um app Android que descobre dispositivos via mDNS/SSDP, vai precisar declarar:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package="com.exemplo.app">

 <uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES"
 android:usesPermissionFlags="neverForLocation" />

 <application
 android:allowBackup="false"
 android:usesCleartextTraffic="false"...>
 </application>
</manifest>

E em Kotlin, ao requisitar acesso à rede local:

val request = NetworkRequest.Builder().addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED_LOCAL_NETWORK).addTransportType(NetworkCapabilities.TRANSPORT_WIFI).build()

val callback = object : ConnectivityManager.NetworkCallback() {
 override fun onAvailable(network: Network) {
 // aqui seu app pode falar com 192.168.x.x
 connectivityManager.bindProcessToNetwork(network)
 }
}
connectivityManager.requestNetwork(request, callback)

Cuidado: apps legítimos que fazem cast (Chromecast, Spotify Connect, AirPlay clones) vão precisar refatorar. Eu já revisei código que faz socket.connect(InetAddress.getByName("192.168.1.1"), 80) sem rede ativa — vai quebrar com a nova política. Seletor nativo do sistema agora medeia esse acesso.

Transparência de Certificados ligada por padrão

CT (Certificate Transparency) é o registro público e auditável de todo certificado emitido. O navegador ou SO valida SCTs (Signed Certificate Timestamps) durante o handshake. Se uma CA for comprometida e emitir um cert falso para o seu domínio, o log público vai denunciar em horas.

Android 17 ativa isso por padrão. Para quem opera infraestrutura, isso significa que seu cert precisa estar logado em pelo menos dois logs de operadores distintos (ex.: Google Pilot + Let’s Encrypt Oak). Para validar via OpenSSL:

echo | openssl s_client -connect meusite.com:443 -servername meusite.com 2>/dev/null | \
 openssl x509 -noout -text | grep -A2 "CT Precertificate SCTs"

Se aparecer No SCTs found, seu certificado vai começar a ser rejeitado em conexões a partir do Android 17. Renove pelo Let’s Encrypt ou ajuste a cadeia — o staging do Google já exige SCTs há anos.

SMS Blasters e o golpe do downgrade forçado para 2G

SMS blasters são dispositivos portáteis que simulam antenas de telecom. Eles emitem potência suficiente para “afogar” o sinal 4G/5G do seu telefone nas proximidades, forçando o modem a tentar reconectar. Como o modem precisa de fallback, ele aceita uma conexão 2G — protocolo sem autenticação mútua, com A5/1 quebrado há décadas. A partir daí, injetam SMS de phishing que parecem vir do seu banco.

Antes, a única defesa era desligar o 2G manualmente nas configurações de rede — e poucos usuários sabiam fazer isso. O Android 17 permite que a operadora desligue o 2G direto na rede, sem o usuário tocar em nada. É a primeira vez que vejo uma defesa contra downgrade coercitivo funcionando no nível do carrier, não do dispositivo.

Implicação prática para devs: se você ainda usa SMS como segundo fator, esse vetor de ataque ficou mais difícil de explorar, mas não morreu. Migre para TOTP, push notification ou WebAuthn. O fim do SMS como MFA não é questão de moda, é questão de tempo.

Na Prática: checklist para devs antes do rollout

  1. Ative DNS privado nos seus dispositivos de teste. Via adb: adb shell settings put global private_dns_mode hostname e adb shell settings put global private_dns_specifier dns.google.
  2. Verifique suporte ECH no seu backend. Se estiver atrás de Cloudflare, Fastly ou Akamai, ative no painel. Origin precisa de TLS 1.3 limpo.
  3. Atualize manifests Android. Declare NEARBY_WIFI_DEVICES onde for necessário e revise chamadas a InetAddress de faixas privadas.
  4. Audite CT dos seus certificados. Renove se necessário e monitore logs via crt.sh.
  5. Substitua SMS como 2FA. Qualquer coisa que dependa de SMS hoje é débito técnico.

Erros comuns que eu já vi em produção

1. Achar que ECH torna a navegação anônima. Não torna. O ISP ainda vê o IP de destino, o volume de tráfego, os horários. ECH só esconde qual domínio você acessou dentro daquela conexão.

2. Ignorar o requisito de DNS encriptado. Sem DoH/DoT funcionando, o ECH não inicializa. Configurou DNS público mas esqueceu de validar se o Android está realmente usando? Rode dig do próprio dispositivo após ativar.

3. Fazer varredura de rede local em background. Apps que faziam isso para “telemetria” agora vão precisar de permissão explícita ou vão silenciosamente parar de funcionar. Planeje o fallback.

4. Não testar com CT ativo. Eu já quebrei staging porque o cert tinha sido emitido sem SCT por uma CA interna. O Chrome ignorou, o Android 17 não vai.

5. Confundir privacidade de DNS com privacidade de tráfego.DNS encriptado impede que a operadora veja as consultas, mas o IP de destino continua visível no handshake TCP. Para tráfego real, só VPN ou Tor entregam o pacote completo.

FAQ

O que é ECH no Android 17?

Encrypted Client Hello cifra o campo SNI do TLS handshake, que antes ia em texto claro e revelava o domínio visitado. Funciona combinado com DNS privado (DoH/DoT) que entrega a chave pública necessária.

Como ativar DNS Privado no Android?

Em Configurações → Rede → DNS Privado, escolha “Nome do host do provedor” e coloque dns.google ou one.one.one.one. A partir do Android 17, vem habilitado por padrão na maioria dos perfis.

Como impedir que um app escaneie minha rede local?

Você não precisa — o Android 17 passa a exigir permissão explícita via prompt do sistema, igual câmera e microfone. Apps sem a permissão NEARBY_WIFI_DEVICES simplesmente não enxergam outros dispositivos na sua rede Wi-Fi.

O Android 17 bloqueia SMS Blasters totalmente?

Não totalmente. Ele remove o vetor mais comum — o downgrade coercitivo para 2G — quando a operadora participa do programa. Atacantes ainda podem explorar outras camadas (malware instalado, SIM swap, redes sociais). Mas phishing por SMS via 2G forçado deixa de escalar.

Como saber se meu site tem suporte a ECH?

Use curl --ech true -v https://seusite.com ou dig +short HTTPS seusite.com e procure por ech= na resposta. Se estiver atrás de Cloudflare, ative em Network → Encrypted Client Hello.

O Android 17 não é uma revolução — é a Google fazendo o trabalho de base que deveria ter feito há cinco anos. Mas a combinação ECH + DNS privado + CT + bloqueio de 2G representa o maior salto de privacidade padrão em uma versão do sistema desde a separação de perfis de trabalho. Para quem desenvolve, é a hora de auditar backend, manifest e fluxo de autenticação. Quem deixar para depois, vai descobrir em produção.


💬 Comente no blog

Gostou? Me segue no GitHub e deixa um comentário se tiver dúvida ou quiser aprofundar algum ponto.

Y

Yuri Sousa

Front-End Developer / Designer

Desenvolvedor apaixonado por criar experiências digitais acessíveis e visualmente perfeitas. Escrevo sobre desenvolvimento web, design e tecnologia.