<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Leehendry Pauletto</title>
    <description>The latest articles on DEV Community by Leehendry Pauletto (@leehendryp).</description>
    <link>https://dev.to/leehendryp</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F361250%2Fe8e84473-13ff-4429-be9d-6e5a6658dd0f.png</url>
      <title>DEV Community: Leehendry Pauletto</title>
      <link>https://dev.to/leehendryp</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/leehendryp"/>
    <language>en</language>
    <item>
      <title>Evite subir chaves de API para o GitHub em seu projeto Android, veja como.</title>
      <dc:creator>Leehendry Pauletto</dc:creator>
      <pubDate>Fri, 04 Dec 2020 16:10:58 +0000</pubDate>
      <link>https://dev.to/leehendryp/evite-subir-chaves-de-api-para-o-github-em-seu-projeto-android-veja-como-1ge6</link>
      <guid>https://dev.to/leehendryp/evite-subir-chaves-de-api-para-o-github-em-seu-projeto-android-veja-como-1ge6</guid>
      <description>&lt;h6&gt;
  
  
  Imagem de capa por &lt;a href="https://unsplash.com/@brunus"&gt;Bruno Martins @ Unsplash&lt;/a&gt;
&lt;/h6&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Aviso&lt;/strong&gt;
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Nenhuma medida por si só tornará nossas aplicações seguras. A segurança dum app depende duma combinação de medidas, e &lt;a href="https://olhardigital.com.br/2020/05/18/noticias/computador-quantico-deve-quebrar-criptografia-do-bitcoin-em-dois-anos"&gt;até mesmo as sofisticadas podem ser quebradas&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;Dito isso, destaco que este tutorial não consiste numa bala de prata para todos os nossos problemas de segurança, mas numa medida que pode deixar nossos apps menos sujeitos a vazamentos de dados.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Não li, nem lerei&lt;/strong&gt;
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Chaves de API são utilizadas para autenticação de clientes em serviços específicos;&lt;/li&gt;
&lt;li&gt;A revelação de informações sensíveis, como as chaves de API, pode acarretar usos e consequências não planejados;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;BuildConfig&lt;/code&gt; do Gradle permite ao nosso projeto ler dados sensíveis contidos num arquivo local, na forma de código gerado.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Contexto&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;A divulgação de dados sensíveis tem o potencial de causar danos tanto aos nossos próprios interesses &lt;a href="https://saude.estadao.com.br/noticias/geral,vazamento-de-senha-do-ministerio-da-saude-expoe-dados-de-16-milhoes-de-pacientes-de-covid,70003528583"&gt;quanto aos das pessoas impactadas por nossos projetos&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Embora tenha focado em chaves de API, outros dados sensíveis como &lt;em&gt;endpoints&lt;/em&gt; e &lt;em&gt;credenciais&lt;/em&gt; também podem ser guardados localmente com a abordagem descrita aqui.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Os quês&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Antes de tudo, é melhor termos a certeza de que estamos falando das mesmas coisas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cliente&lt;/strong&gt; refere-se ao software ou hardware que faz uso dos &lt;strong&gt;serviços&lt;/strong&gt; disponíveis num servidor, no modelo cliente-servidor &lt;a href="https://pt.wikipedia.org/wiki/Modelo_cliente%E2%80%93servidor"&gt;&amp;lt;1&amp;gt;&lt;/a&gt;;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;API&lt;/strong&gt; significa Interface de Programação de Aplicativos, que, em termos gerais, é um conjunto de regras a serem observadas na comunicação entre programas, geralmente um cliente e um serviço &lt;a href="https://www.origiweb.com.br/dicionario-de-tecnologia/API"&gt;&amp;lt;2&amp;gt;&lt;/a&gt;;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Segredo, token ou chave de API&lt;/strong&gt; é um identificador único utilizado na autenticação de um cliente num serviço&lt;a href="https://cloud.ibm.com/docs/account?topic=account-manapikey&amp;amp;locale=pt-BR"&gt;&amp;lt;3&amp;gt;&lt;/a&gt;;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Geração de código&lt;/strong&gt; é o processo pelo qual um compilador converte representações de código em instruções que podem ser prontamente executadas pelo dispositivo &lt;a href="https://pt.wikipedia.org/wiki/Programa%C3%A7%C3%A3o_autom%C3%A1tica"&gt;&amp;lt;4&amp;gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Os porquês&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Chaves de API permitem identificar clientes e são geradas para fins específicos. Por isso, é comum que a conta do cliente incorra em custos de acordo com as quotas de uso do serviço. - Google Maps Platform é um bom exemplo disso, já que &lt;a href="https://cloud.google.com/maps-platform/pricing?hl=pt"&gt;os preços variam conforme a utilização&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;Evitar a revelação dessas chaves é fundamental na prevenção de usos indevidos.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Apesar disso, o versionamento de chaves de API é um erro que não apenas eu mesmo cometi no passado, mas que também vi colegas de profissão cometerem, independentemente da experiência.&lt;/p&gt;

&lt;p&gt;A verdade é que, infelizmente, práticas de Segurança da Informação ainda são pouquíssimo divulgadas nas nossas comunidades de desenvolvimento.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;O como&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;a href="https://developer.android.com/studio/build/gradle-tips"&gt;classe &lt;code&gt;BuildConfig&lt;/code&gt; do Gradle&lt;/a&gt; 
permite a leitura de valores a partir de arquivos locais e a disponibilização deles na forma de código gerado;&lt;/li&gt;
&lt;li&gt;Contanto que indiquemos &lt;em&gt;corretamente&lt;/em&gt; os arquivos no &lt;code&gt;.gitignore&lt;/code&gt;, a divulgação das nossas chaves de API no GitHub, GitLab e afins não deverá ser um problema.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;O código&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;São oito as etapas:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Criar &lt;code&gt;keys.properties&lt;/code&gt; na raiz
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Na raiz do projeto, crie um arquivo chamado &lt;code&gt;keys.properties&lt;/code&gt; e adicione a ele a chave da API desta forma:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;API_KEY_HERE&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. Adicionar o caminho do arquivo &lt;code&gt;.gitignore&lt;/code&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Muita atenção a esta etapa, pois o &lt;code&gt;.gitignore&lt;/code&gt; é que indica quais arquivos ficam fora do versionamento!&lt;/li&gt;
&lt;li&gt;Para prevenir o versionamento do &lt;code&gt;keys.properties&lt;/code&gt;, adicione o caminho do arquivo ao &lt;code&gt;.gitignore&lt;/code&gt; desta forma:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;properties&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Rode no terminal o comando &lt;code&gt;git status&lt;/code&gt;. O arquivo &lt;code&gt;keys.properties&lt;/code&gt; &lt;strong&gt;não deverá&lt;/strong&gt; estar listado para versionamento. Caso esteja, significa que a configuração do &lt;code&gt;.gitignore&lt;/code&gt; está &lt;em&gt;errada&lt;/em&gt;! Repita a etapa.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  3. Criar &lt;code&gt;keys.gradle&lt;/code&gt; na raiz
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Para recuperar os valores do &lt;code&gt;keys.properties&lt;/code&gt;, adicione à raiz do projeto um arquivo chamado &lt;code&gt;keys.gradle&lt;/code&gt;, onde o seguinte código &lt;code&gt;Groovy&lt;/code&gt; será adicionado:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Define como carregar as informações do arquivo local&lt;/span&gt;
&lt;span class="kt"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;getStringFromFile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;property&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Properties&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Properties&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;load&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;rootProject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;file&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;newDataInputStream&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;property&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


&lt;span class="c1"&gt;// Indica keys.properties como o arquivo para recuperação dos valores&lt;/span&gt;
&lt;span class="kt"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;getStringFromKeysFile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;property&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;getStringFromFile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'keys.properties'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;property&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


&lt;span class="c1"&gt;// Expõe a chave definida no keys.properties como uma variável para uso em todo o projeto&lt;/span&gt;
&lt;span class="n"&gt;ext&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;keys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"apiKey"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;getStringFromKeysFile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'api.key'&lt;/span&gt;&lt;span class="o"&gt;),]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  4. Importe &lt;code&gt;keys.gradle&lt;/code&gt; dentro do &lt;code&gt;project/build.gradle&lt;/code&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Para utilizar os métodos definidos no &lt;code&gt;keys.gradle&lt;/code&gt;, importe o arquivo dentro do &lt;code&gt;build.gradle&lt;/code&gt; do projeto:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;buildscript&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;apply&lt;/span&gt; &lt;span class="nl"&gt;from:&lt;/span&gt; &lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;rootProject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;file&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"keys.gradle"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

    &lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;A esta altura, a &lt;code&gt;BuildConfig&lt;/code&gt; já consegue automaticamente converter nossa chave em código compilado -- mas só faremos isso na etapa 6.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  5. Definir uma constante para a chave dentro do &lt;code&gt;app/build.gradle&lt;/code&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Defina uma constante chamada &lt;code&gt;API_KEY&lt;/code&gt; no &lt;code&gt;build.gradle&lt;/code&gt; do app desta forma:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;android&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

&lt;span class="o"&gt;...&lt;/span&gt;

    &lt;span class="n"&gt;buildTypes&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

     &lt;span class="c1"&gt;// Embora esteja configurado para 'debug', certifique-se de quais build variants (debug, staging, release etc) precisarão da chave:&lt;/span&gt;
        &lt;span class="n"&gt;debug&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

            &lt;span class="o"&gt;...&lt;/span&gt;

            &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;buildConfigField&lt;/span&gt; &lt;span class="s2"&gt;"String"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"API_KEY"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apiKey&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  6. Limpar e recompilar o projeto
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Para que o código seja efetivamente gerado, selecione &lt;em&gt;Build &amp;gt; Clean Project&lt;/em&gt; e depois &lt;em&gt;Build &amp;gt; Rebuild Project&lt;/em&gt; no menu superior do Android Studio.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  7. Chamar a variável via &lt;code&gt;BuildConfig&lt;/code&gt; dentro do projeto
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Chame a constante via &lt;code&gt;BuildConfig.API_KEY&lt;/code&gt;, conforme etapa 5, onde for necessário no código. Por exemplo:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CustomApplication&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Application&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="nc"&gt;Firebase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;BuildConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  8. Compartilhar o arquivo &lt;code&gt;keys.properties&lt;/code&gt; de forma segura dentro do time
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Já que evitamos o versionamento da chave da API, é necessário utilizar uma maneira segura de compartilhar o &lt;code&gt;keys.properties&lt;/code&gt; entre as pessoas da equipe;&lt;/li&gt;
&lt;li&gt;Caso seu trabalho conte com um time de Segurança da Informação, verifique com ele qual a melhor forma de compartilhar o arquivo;&lt;/li&gt;
&lt;li&gt;Do contrário, ferramentas como 1Password podem ajudar, já que permitem a gestão de direitos de acesso aos arquivos.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Considerações finais&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Outras informações sensíveis como &lt;em&gt;endpoint&lt;/em&gt; e &lt;em&gt;credenciais&lt;/em&gt; também pode sem mantidas localmente com essa abordagem;&lt;/li&gt;
&lt;li&gt;Nomes como &lt;code&gt;keys.properties&lt;/code&gt;, &lt;code&gt;api.key&lt;/code&gt;, &lt;code&gt;keys.gradle&lt;/code&gt; e &lt;code&gt;API_KEY&lt;/code&gt; são arbitrários -- apenas mantenha as extensões (&lt;code&gt;.properties&lt;/code&gt;, &lt;code&gt;.key&lt;/code&gt;, &lt;code&gt;.gradle&lt;/code&gt;) ao renomear;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NOTE QUE&lt;/strong&gt; &lt;code&gt;BuildConfig&lt;/code&gt; gera &lt;em&gt;código compilado&lt;/em&gt;, o que significa que engenharia reversa do &lt;code&gt;.apk&lt;/code&gt; ainda pode expor chaves de API e outros segredos;&lt;/li&gt;
&lt;li&gt;Apenas a combinação de medidas de segurança pode nos ajudar a manter nossos apps seguros. Busque também ferramentas de otimização e ofuscação de código como &lt;a href="https://developer.android.com/studio/build/shrink-code"&gt;R8&lt;/a&gt; para reduzir as chances de vazamento de dados.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Agradecimentos especiais ao Victor Vieira por me ensinar essa abordagem há um ano; e ao Walmyr Carvalho por me estimular a escrever aqui no dev.to!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>tutorial</category>
      <category>security</category>
      <category>github</category>
    </item>
    <item>
      <title>Avoid uploading API keys and other sensitive info to GitHub on Android, here's how.</title>
      <dc:creator>Leehendry Pauletto</dc:creator>
      <pubDate>Thu, 03 Dec 2020 22:39:33 +0000</pubDate>
      <link>https://dev.to/leehendryp/avoid-versioning-api-keys-and-sensitive-info-on-android-here-s-how-56e1</link>
      <guid>https://dev.to/leehendryp/avoid-versioning-api-keys-and-sensitive-info-on-android-here-s-how-56e1</guid>
      <description>&lt;h6&gt;
  
  
  Cover image by &lt;a href="https://unsplash.com/@brunus"&gt;Bruno Martins @ Unsplash&lt;/a&gt;
&lt;/h6&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Disclaimer&lt;/strong&gt;
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;There’s no measure alone that will make your app secure. Securing an app requires a combination of measures, and &lt;a href="https://www.techtimes.com/articles/246148/20191122/can-quantum-computing-break-the-blockchain.htm"&gt;even sophisticated ones can eventually be cracked&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;That said, this tutorial is not a silver bullet for all our security problems, but one of those measures that can make our apps less prone to information leak.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;TL;DR&lt;/strong&gt;
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;API keys are used to authenticate users on specific services;&lt;/li&gt;
&lt;li&gt;Disclosure of sensitive info such as keys can lead to unintended use and consequences;&lt;/li&gt;
&lt;li&gt;Gradle's &lt;code&gt;BuildConfig&lt;/code&gt; can be used to read sensitive values from a local file and provide them to our project via generated code.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Context&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Disclosing sensitive info may result in damage not only to ourselves, but &lt;a href="https://www.zdnet.com/article/personal-data-of-16-million-brazilian-covid-19-patients-exposed-online/"&gt;also to users of our projects&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Although I have focused on API keys, other sensitive info like &lt;em&gt;endpoints&lt;/em&gt; and &lt;em&gt;credentials&lt;/em&gt; can also be kept locally with this approach.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Whats&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;First of all, let's make sure we're talking about the same stuff:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Client&lt;/strong&gt; refers to software or hardware making use of &lt;strong&gt;services&lt;/strong&gt; provided by a &lt;strong&gt;server&lt;/strong&gt;, in a client-server model &lt;a href="https://techterms.com/definition/client-server_model"&gt;&amp;lt;1&amp;gt;&lt;/a&gt;;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;API&lt;/strong&gt; stands for Application Programming Interface, which is basically a set of rules you must observe for communication between programs, often a client and a service &lt;a href="https://techterms.com/definition/api"&gt;&amp;lt;2&amp;gt;&lt;/a&gt;;  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;API secret, token or key&lt;/strong&gt; is a unique identifier used to authenticate a client on an API service &lt;a href="https://en.wikipedia.org/wiki/Application_programming_interface_key"&gt;&amp;lt;3&amp;gt;&lt;/a&gt;;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Code generation&lt;/strong&gt; is a process by which a compiler can convert representations of code into ones that can be readily executed by the machine &lt;a href="https://en.wikipedia.org/wiki/Code_generation_(compiler)"&gt;&amp;lt;4&amp;gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Whys&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;API keys are a way of identifying users and are generated for specific purposes. Due to that, user accounts are often charged second to service use quotas. - Google Maps Platform is a good example of that, as &lt;a href="https://cloud.google.com/maps-platform/pricing"&gt;prices vary depending on how services are used&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Avoiding public disclosure of such keys is fundamental to prevent unintended service use.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Despite that, API key versioning is a mistake that not only have I committed in the past, but also seen committed by fellow junior and more senior developers alike.&lt;/p&gt;

&lt;p&gt;Unfortunately, Information Security -- or Info Sec -- practices are still poorly spread within our developer communities.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The How&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://developer.android.com/studio/build/gradle-tips"&gt;Gradle's &lt;code&gt;BuildConfig&lt;/code&gt; class&lt;/a&gt; allows us to read values from local files and then generate code to be used by our app. &lt;/li&gt;
&lt;li&gt;As long as we &lt;em&gt;correctly&lt;/em&gt; add such files to &lt;code&gt;.gitignore&lt;/code&gt;, public disclosure of our API keys on GitHub, GitLab or the likes should be less of a problem.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;The Code&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;There are eight steps:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Create &lt;code&gt;keys.properties&lt;/code&gt; at the root
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;At the root of the project, create a file named &lt;code&gt;keys.properties&lt;/code&gt; and add your API key to the file as such:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;API_KEY_HERE&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. Add file path to &lt;code&gt;.gitignore&lt;/code&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;To prevent the versioning of &lt;code&gt;keys.properties&lt;/code&gt;, add the file path to &lt;code&gt;.gitignore&lt;/code&gt; file as such:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;properties&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Create &lt;code&gt;keys.gradle&lt;/code&gt; at the root
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;In order to retrieve the keys in &lt;code&gt;keys.properties&lt;/code&gt;, add to the root of the project a file named &lt;code&gt;keys.gradle&lt;/code&gt;, where the following &lt;code&gt;Groovy&lt;/code&gt; code should be added:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Define how to load a string from a properties file:&lt;/span&gt;
&lt;span class="kt"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;getStringFromFile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;property&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Properties&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Properties&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;load&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;rootProject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;file&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;newDataInputStream&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;property&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


&lt;span class="c1"&gt;// Specify keys.properties file as the source&lt;/span&gt;
&lt;span class="kt"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;getStringFromKeysFile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;property&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;getStringFromFile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'keys.properties'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;property&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


&lt;span class="c1"&gt;// Expose the key defined in keys.properties as a variable available for the whole project&lt;/span&gt;
&lt;span class="n"&gt;ext&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;keys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"apiKey"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;getStringFromKeysFile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'api.key'&lt;/span&gt;&lt;span class="o"&gt;),]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  4. Import &lt;code&gt;keys.gradle&lt;/code&gt; inside &lt;code&gt;project/build.gradle&lt;/code&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;In order to use the methods defined in &lt;code&gt;keys.gradle&lt;/code&gt;, import the file inside the &lt;code&gt;build.gradle&lt;/code&gt; file of the project:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;buildscript&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;apply&lt;/span&gt; &lt;span class="nl"&gt;from:&lt;/span&gt; &lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;rootProject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;file&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"keys.gradle"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

    &lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;At this point, &lt;code&gt;BuildConfig&lt;/code&gt; is already able to automatically convert the key into compiled code -- but we'll do that on the step 6. &lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  5. Define a constant for the key inside the &lt;code&gt;app/build.gradle&lt;/code&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Define a constant named &lt;code&gt;API_KEY&lt;/code&gt; in the &lt;code&gt;build.gradle&lt;/code&gt; file of the app, as follows:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;android&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

&lt;span class="o"&gt;...&lt;/span&gt;

    &lt;span class="n"&gt;buildTypes&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

     &lt;span class="c1"&gt;// Although it's set to 'debug', certify what build variants (say debug, staging, release) will need to access the key:&lt;/span&gt;
        &lt;span class="n"&gt;debug&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

            &lt;span class="o"&gt;...&lt;/span&gt;

            &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;buildConfigField&lt;/span&gt; &lt;span class="s2"&gt;"String"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"API_KEY"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apiKey&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  6. Clean and recompile the project
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;For the code to be effectively generated, select &lt;em&gt;Build &amp;gt; Clean Project&lt;/em&gt; and then &lt;em&gt;Build &amp;gt; Rebuild Project&lt;/em&gt; at the upper menu of Android Studio.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  7. Call the key variable via &lt;code&gt;BuildConfig&lt;/code&gt; inside the project
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Call the constant named in step 5 as &lt;code&gt;BuildConfig.API_KEY&lt;/code&gt; where it's needed. For example:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CustomApplication&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Application&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="nc"&gt;Firebase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;BuildConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  8. Share &lt;code&gt;keys.properties&lt;/code&gt; in a secure manner inside your team
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Since we have avoided the versioning of the API key, we need a secure way of sharing the &lt;code&gt;keys.properties&lt;/code&gt; file between the members of the development team;&lt;/li&gt;
&lt;li&gt;If your company has an Info Sec team, check with them what's the best way to share the file;&lt;/li&gt;
&lt;li&gt;If not, solutions like 1Password may be a good choice to do so, since it offers manners of managing user privileges.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Final considerations&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Other sensitive info like &lt;em&gt;endpoints&lt;/em&gt; and &lt;em&gt;credentials&lt;/em&gt; can also be kept locally with this approach;&lt;/li&gt;
&lt;li&gt;Names like &lt;code&gt;keys.properties&lt;/code&gt;, &lt;code&gt;api.key&lt;/code&gt;, &lt;code&gt;keys.gradle&lt;/code&gt; and &lt;code&gt;API_KEY&lt;/code&gt; are all arbitrary -- just keep their extensions (&lt;code&gt;.properties&lt;/code&gt;, &lt;code&gt;.key&lt;/code&gt;, &lt;code&gt;.gradle&lt;/code&gt;) when renaming them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NOTE THAT&lt;/strong&gt; &lt;code&gt;BuildConfig&lt;/code&gt; generates compiled code, which means that reverse engineering our app's &lt;code&gt;.apk&lt;/code&gt; could still expose API keys and other secrets;&lt;/li&gt;
&lt;li&gt;Only a combination of security measures can help us keep our apps secure. Look into code optimisation and obfuscation tools such as &lt;a href="https://developer.android.com/studio/build/shrink-code"&gt;R8&lt;/a&gt; to diminish the chances of info leaks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Special thanks to Victor Vieira for teaching me the approach a year back; and to Walmyr Carvalho for stimulating me to write on dev.to!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>tutorial</category>
      <category>security</category>
      <category>github</category>
    </item>
  </channel>
</rss>
