Estratégia para manter informações secretas, como chaves de API fora do controle de origem?

209

Estou trabalhando em um site que permitirá que os usuários façam login usando credenciais OAuth dos tipos Twitter, Google etc. Para fazer isso, preciso registrar-me com esses vários provedores e obter uma chave de API super secreta que tenho que proteger com promessas contra várias partes do corpo. Se minha chave for ganked, a peça é arrancada.

A chave da API precisa viajar com minha origem, pois é usada em tempo de execução para executar solicitações de autenticação. No meu caso, a chave deve existir dentro do aplicativo em um arquivo de configuração ou dentro do próprio código. Isso não é um problema quando eu construo e publico de uma única máquina. No entanto, quando lançamos o controle de origem no mix, as coisas ficam mais complicadas.

Como sou um bastardo barato, prefiro muito mais usar serviços gratuitos de controle de código-fonte, como o TFS na nuvem ou o GitHub. Isso me deixa com um pequeno enigma:

Como posso manter meu corpo intacto quando minhas chaves de API estão no meu código e meu código está disponível em um repositório público?

Eu posso pensar em várias formas de lidar com isso, mas nenhuma delas é satisfatória.

  • Eu poderia remover todas as informações privadas do código e editá-las novamente após a implantação. Isso seria uma dor severa para implementar (não detalharei as muitas maneiras) e não é uma opção.
  • Eu poderia criptografá-lo. Mas como eu tenho que decifrá-lo, qualquer pessoa com a fonte pode descobrir como fazê-lo. Sem sentido.
  • Eu poderia pagar pelo controle de fonte privada. LOL j / k gasta dinheiro? Por favor.
  • Eu poderia usar recursos de idioma para separar informações confidenciais do restante da minha fonte e, portanto, mantê-las no controle de origem. Isso é o que estou fazendo agora, mas pode ser facilmente confundido por meio de um erro de verificação no arquivo secreto.

Estou realmente procurando uma maneira garantida de garantir que não compartilhe minhas privações com o mundo (exceto no snapchat), que funcionará sem problemas durante o desenvolvimento, a depuração e a implantação, além de ser à prova de falhas. Isso é completamente irrealista. Então o que realisticamente posso fazer?

Detalhes técnicos: VS2012, C # 4.5, controle de origem será TF service ou GitHub. Atualmente usando uma classe parcial para dividir as chaves sensíveis em um arquivo separado .cs que não será adicionado ao controle de origem. Eu acho que o GitHub pode ter a vantagem, pois o .gitignore pode ser usado para garantir que o arquivo de classe parcial não seja verificado, mas eu estraguei tudo antes. Estou esperando por um "oh, problema comum, é assim que você faz", mas eu posso ter que se contentar com "que não chupa tanto quanto poderia ter",: /

    
por Will 21.07.2013 / 22:18
fonte

12 respostas

124

Não coloque suas informações secretas em seu código. Coloque-o em um arquivo de configuração que é lido pelo seu código na inicialização. Os arquivos de configuração não devem ser colocados no controle de versão, a menos que sejam os "padrões de fábrica", e então eles não devem ter nenhuma informação privada.

Veja também a pergunta Controle de versão e arquivo de configuração pessoal . como fazer isso bem.

    
por 21.07.2013 / 22:43
fonte
28

Você pode colocar todas as chaves privadas / protegidas como variáveis de ambiente do sistema. Seu arquivo de configuração ficará assim:

private.key=#{systemEnvironment['PRIVATE_KEY']}

É assim que lidamos com esses casos e nada entra no código. Ele funciona muito bem combinado com diferentes arquivos e perfis de propriedades. Usamos arquivos de propriedades diferentes para diferentes ambientes. Em nosso ambiente de desenvolvimento local, colocamos as chaves de desenvolvimento nos arquivos de propriedades para simplificar a configuração local:

private.key=A_DEVELOPMENT_LONG_KEY
    
por 22.07.2013 / 13:40
fonte
27

Caminho Pure Git

  • .gitignore incluiu o arquivo com dados privados
  • Use uma ramificação local, na qual você substitui TEMPLATE por DATA
  • Use os filtros smudge / clean, nos quais o script do filtro (local) realiza a substituição bidirecional TEMPLATE < - > %código%

Caminho mercurial

  • MQ-patch (es) sobre o código simulado, que substitui DATA por TEMPLATE (conjuntos de alterações são públicos, o patch é privado)
  • Extensão de palavra-chave com palavras-chave especialmente projetadas (expandida apenas em seu diretório de trabalho )

Maneira agnóstica do SCM

  • Substituir palavras-chave como parte do processo de criação / implementação
por 21.07.2013 / 23:29
fonte
14

Isso é muito específico para Android / Gradle, mas você pode definir as chaves em seu arquivo global gradle.properties localizado em user home/.gradle/ . Isso também é útil, já que você pode usar diferentes propriedades, dependendo do tipo de buildType ou sabor, ou seja, API para dev e outro diferente para release.

gradle.properties

MY_PRIVATE_API_KEY=12356abcefg

build.gradle

buildTypes {
        debug{
            buildConfigField("String", "GOOGLE_VERIFICATION_API_KEY", "\"" + MY_PRIVATE_API_KEY +"\"")
            minifyEnabled false
            applicationIdSuffix ".debug"
            }
        }

No código você faria referência a isso

String myAPI = BuildConfig.GOOGLE_VERIFICATION_API_KEY;
    
por 29.05.2015 / 20:40
fonte
13

Eu coloco segredos no (s) arquivo (s) criptografado (s). A frase secreta é fornecida quando o sistema é iniciado ou é armazenada em um arquivo pequeno que eu não confirmo. É legal que o Emacs gerencie alegremente esses arquivos criptografados. Por exemplo, o arquivo init do emacs inclui: (load "segredos.el.gpg"), que simplesmente funciona - solicitando a senha nas raras ocasiões em que inicio o editor. Eu não me preocupo com alguém quebrando a criptografia.

    
por 09.12.2013 / 06:16
fonte
11

Você não deve distribuir essa chave com seu aplicativo ou armazená-lo no repositório do código-fonte. Esta pergunta está perguntando como fazer isso, e isso não é o que normalmente é feito.

Aplicativo da Web para dispositivos móveis

Para Android / iPhone, o dispositivo deve solicitar a KEY do seu próprio serviço da Web quando o aplicativo for executado pela primeira vez. A chave é então armazenada em um local seguro. A chave deve ser alterada ou revogada pelo editor. Seu serviço da web pode publicar uma nova chave.

Aplicativo da Web hospedado

Os clientes que usam uma licença do seu software precisarão inserir a chave manualmente ao configurar o software pela primeira vez. Você pode dar a todos a mesma chave, chaves diferentes ou eles próprios.

Código Fonte Publicado

Você armazena seu código-fonte em um repositório público, mas não na KEY. Na configuração do arquivo, você adiciona as linhas * chave de lugar aqui * . Quando um desenvolvedor usa seu código-fonte, ele faz uma cópia do arquivo sample.cfg e adiciona sua própria chave.

Você não mantém seu arquivo config.cfg usado para desenvolvimento ou produção no repositório.

    
por 23.07.2013 / 21:28
fonte
5

Use variáveis de ambiente para itens secretos que mudam para cada servidor.

link

Como usá-los depende do idioma.

    
por 23.07.2013 / 20:39
fonte
4

Acho que esse é um problema que todos tiveram problemas em algum momento.

Aqui está um fluxo de trabalho que usei, que pode funcionar para você. Ele usa .gitignore com uma torção:

  1. Todos os arquivos de configuração vão em uma pasta especial (com arquivos de configuração de amostra - opcionais)
  2. Todos os arquivos de configuração estão incluídos no .gitignore, para que eles não sejam públicos
  3. Configure um servidor gitolite (ou seu servidor git favorito) em uma caixa privada
  4. Adicione um repo com todos os arquivos de configuração no servidor privado
  5. Adicione um script para copiar arquivos de configuração para a pasta especial no repositório principal (opcional)

Agora, você pode clonar o repositório de configuração em qualquer sistema de desenvolvimento e implantação. Basta executar o script para copiar os arquivos para a pasta correta e pronto.

Você ainda recebe todos os doces do GitHub, compartilha seu código com o mundo e os dados confidenciais nunca estão no repositório principal, para que eles não sejam públicos. Eles ainda são apenas uma atração e uma cópia de qualquer sistema de implantação.

Eu uso uma caixa de 15 $ / ano para o servidor git privado, mas você também pode configurar uma em casa, de acordo com o requisito do cheapskate; -)

PS: Você também pode usar um submódulo git ( link ), mas eu sempre esqueço os comandos, então quick & regras sujas!

    
por 08.12.2013 / 22:24
fonte
2

Use criptografia, mas forneça uma chave mestra na inicialização, como uma senha no console, em um arquivo que apenas o usuário do processo possa ler ou em um armazenamento de chaves fornecido pelo sistema, como o keychain do Mac OS ou o keystore do Windows.

Para uma entrega contínua, você precisará de várias chaves gravadas em algum lugar. A configuração deve ser demarcada do código, mas faz muito sentido mantê-la sob controle de revisão.

    
por 23.07.2013 / 12:15
fonte
1

3 Estratégias, ainda não mencionadas (?)

No check-in ou em uma pré-verificação do VCS no gancho

  • pesquise por strings com entropia alta, por exemplo detect-secrets
  • regex procura por padrões de chave de API bem conhecidos. As chaves AKIA * da AWS são um exemplo, git-secrets é uma ferramenta baseada nisso. Além disso, nomes de variáveis como 'senha' com atribuição constante.
  • procure por segredos conhecidos - você conhece seus segredos, pesquisa texto para eles. Ou use uma ferramenta, eu escrevi esta prova de conceito .

Estratégias já mencionadas

  • armazenar em arquivo fora da árvore de origem
  • tem na árvore fonte, mas diz ao VCS para ignorá-lo
  • as variáveis de ambiente são uma variação no armazenamento de dados fora da árvore de origem
  • apenas não forneça os valiosos segredos aos desenvolvedores
por 24.07.2018 / 05:02
fonte
0

Mantenha informações privadas fora do seu controle de origem. Crie um padrão não carregado para distribuição e faça com que seu VCS ignore o real. Seu processo de instalação (manual, configure / build ou wizard) deve manipular a criação e o preenchimento do novo arquivo. Como opção, modifique as permissões no arquivo para garantir que apenas o usuário necessário (servidor da Web?) Possa lê-lo.

Benefícios:

  • Não assume entidade de desenvolvimento == entidade de produção
  • Não assume que todos os colaboradores / revisores de código são confiáveis
  • Evite erros fáceis mantendo-os fora do controle de versão
  • Fácil de automatizar instalações com configuração personalizada para controle de qualidade / construções

Se você já estiver fazendo isso e estiver verificando isso acidentalmente, adicione-o ao .gitignore do seu projeto. Isso tornará impossível fazer novamente.

Existem muitos hosts Git gratuitos que fornecem repositórios privados. Embora você nunca deva versionar suas credenciais, você pode ser barato e ter repositórios privados também. ^ _ ^

    
por 27.07.2013 / 06:40
fonte
-2

Em vez de ter a chave OAuth armazenada como dados brutos em qualquer lugar, por que não executar a cadeia por meio de algum algoritmo de criptografia e armazená-la como um hash salgado? Em seguida, use um arquivo de configuração para restaurá-lo em tempo de execução. Dessa forma, a chave não é armazenada em nenhum lugar, seja armazenada em uma caixa de desenvolvimento ou no próprio servidor.

Você pode até mesmo criar uma API para que seu servidor gere automaticamente uma nova chave de API com salgados e hash por solicitação, assim nem sua equipe poderá ver a origem do OAuth.

Editar: Talvez tente a Biblioteca de criptografia de Javascript da Stanford , ela permite uma criptografia / descriptografia simétrica bastante segura.

    
por 23.07.2013 / 22:19
fonte