Pergunta

arquivos .class Java pode ser compilado com bastante facilidade. Como posso proteger o meu banco de dados se eu tenho que usar os dados de login no código?

Foi útil?

Solução

Nunca senhas de código duro em seu código. Este foi trazido recentemente no Top 25 A maioria dos erros de programação Dangerous :

Hard-codificação de uma conta secreta e senha para o seu software é extremamente conveniente - para qualificados engenheiros inversa. Se a senha é o mesmo em todos os seus softwares, em seguida, cada cliente torna-se vulnerável quando a senha torna-se inevitavelmente conhecido. E porque é hard-coded, é uma enorme dor de corrigir.

Você deve armazenar as informações de configuração, incluindo senhas, em um arquivo separado que o aplicativo lê quando é iniciado. Essa é a única forma real de impedir a senha de vazamento, como resultado de decompilation (nunca compilá-lo em binário para começar).

Para mais informações sobre este erro comum, você pode ler o href="http://cwe.mitre.org/data/definitions/259.html" rel="noreferrer"> CWE-259 artigo . O artigo contém uma mais completas definição, exemplos e muitas outras informações sobre o problema.

Em Java, uma das maneiras mais fáceis de fazer isso é usar a classe Preferências. Ele é projetado para armazenar todos os tipos de configurações do programa, alguns dos quais podem incluir um nome de usuário e senha.

import java.util.prefs.Preferences;

public class DemoApplication {
  Preferences preferences = 
      Preferences.userNodeForPackage(DemoApplication.class);

  public void setCredentials(String username, String password) {
    preferences.put("db_username", username);
    preferences.put("db_password", password);
  }

  public String getUsername() {
    return preferences.get("db_username", null);
  }

  public String getPassword() {
    return preferences.get("db_password", null);
  }

  // your code here
}

No código acima, você poderia chamar o método setCredentials depois de mostrar um askign diálogo para o nome de usuário e senha. Quando você precisa para se conectar ao banco de dados, você pode simplesmente usar os métodos getUsername e getPassword para recuperar os valores armazenados. As credenciais de login não será embutida em seus binários, de modo descompilação não representam um risco de segurança.

Nota importante: Os arquivos de preferência são simplesmente arquivos XML de texto. Certifique-se de tomar as medidas adequadas para impedir que usuários não autorizados visualizem os arquivos raw (permissões UNIX, as permissões do Windows, et cetera). No Linux, pelo menos, este não é um problema, porque chamando Preferences.userNodeForPackage irá criar o arquivo XML no diretório home do usuário atual, que não é legível por outros usuários de qualquer maneira. No Windows, a situação pode ser diferente.

Notas mais importantes: Tem havido muita discussão nos comentários de esta resposta e outros sobre o que a arquitetura correta é para esta situação. A pergunta original realmente não mencionar o contexto no qual o aplicativo está sendo usado, por isso vou falar sobre as duas situações que eu posso pensar. O primeiro é o caso em que a pessoa que usa o programa já sabe (e está autorizada a saber) as credenciais de banco de dados. O segundo é o caso em que você, desenvolvedor, estão tentando manter o segredo credenciais de banco de dados a partir da pessoa que usa o programa.

Primeiro caso: usuário está autorizado a conhecer as credenciais de login do banco de dados

Neste caso, a solução que eu mencionei acima irá funcionar. A classe Preference Java será armazenado o nome de usuário e senha em texto simples, mas o arquivo de preferências só será legível pelo usuário autorizado. O usuário pode simplesmente abrir o arquivo de preferências XML e ler as credenciais de login, mas isso não é um risco de segurança porque o usuário sabia as credenciais para começar.

segundo caso: Tentando credenciais de login esconder do usuário

Este é o caso mais complicado: o usuário não deve conhecer as credenciais de login, mas ainda precisa de acesso ao banco de dados. Neste caso, o usuário que executa o aplicativo tem acesso direto ao banco de dados, o que significa que o programa precisa conhecer as credenciais de login antes do tempo. A solução I mencionados acima não é adequado para este caso. Você pode armazenar as credenciais de login de banco de dados em um arquivo de preferências, mas ele usuário será capaz de ler esse arquivo, uma vez que será o proprietário. De fato,não há realmente nenhuma boa maneira de usar este caso de uma forma segura.

caso correto: Usando uma arquitetura multi-tier

A maneira correta de fazer isso é ter uma camada intermediária, entre o servidor de banco de dados e sua aplicação cliente, que autentica os usuários individuais e permite que um conjunto limitado de operações a serem realizadas. Cada usuário terá suas próprias credenciais de login, mas não para o servidor de banco de dados. As credenciais iria permitir o acesso à camada intermediária (a camada de lógica de negócios) e seria diferente para cada usuário.

Cada usuário teria seu próprio nome de usuário e senha, que podem ser armazenados localmente em um arquivo de preferências sem qualquer risco de segurança. Isso é chamado de três camadas arquitetura (as camadas sendo o seu servidor de banco de dados, servidor de negócios lógica e aplicação do cliente). É mais complexo, mas é realmente a maneira mais segura de fazer esse tipo de coisa.

A ordem básica de operações é a seguinte:

  1. autentica cliente com camada de lógica de negócios usando o usuário pessoal nome de usuário / senha. O nome de usuário e senha são conhecidos para o usuário e não estão relacionados com as credenciais de login do banco de dados de qualquer forma.
  2. Se a autenticação for bem sucedida, o cliente faz uma solicitação para a camada de lógica de negócios pedindo algumas informações do banco de dados. Por exemplo, um inventário de produtos. Note-se que o pedido do cliente não é uma consulta SQL; é uma chamada de procedimento remoto, como getInventoryList.
  3. a lógica de negócios da camada conecta ao banco de dados e recupera as informações solicitadas. A camada de lógica de negócios é responsável pela formação de uma consulta SQL seguro com base no pedido do usuário. Quaisquer parâmetros para a consulta SQL deve ser higienizado para evitar ataques de injeção SQL.
  4. A camada de lógica de negócios envia a lista de inventário de volta para o aplicativo cliente.
  5. O cliente exibe a lista de inventário para o usuário.

Note-se que em todo o processo, a aplicação cliente nunca se conecta diretamente ao banco de dados . A camada de lógica de negócios receber um pedido de um usuário autenticado, processa o pedido do cliente para uma lista de inventário, e só então executa uma consulta SQL.

Outras dicas

Coloque a senha em um arquivo que o aplicativo irá ler. NUNCA inserir senhas em um arquivo de origem. Período.

Ruby tem um módulo conhecido-little chamado DBI :: DBRC para tal uso. Não tenho dúvidas de que o Java tem um equivalente. De qualquer forma, não é difícil escrever um.

Você está escrevendo uma aplicação web? Se assim for, usar JNDI para configurá-lo externamente ao aplicativo. Uma introdução está disponível aqui :

JNDI fornece uma maneira uniforme para um aplicação de encontrar e acesso remoto serviços através da rede. O remoto serviço pode ser qualquer serviço da empresa, incluindo um serviço de mensagens ou um serviço específico do aplicativo, mas, de Naturalmente, uma aplicação JDBC é interessado principalmente em um banco de dados serviço. Uma vez que uma fonte de dados é objecto criado e registrado com um JNDI serviço de nomeação, um aplicativo pode usar o JNDI API para acesso que DataSource objecto, que pode, então, ser usadas para conectar à fonte de dados que representa.

Não importa o que você faça, as informações sensíveis serão armazenados em algum lugar do arquivo. Seu objetivo é torná-lo tão difícil de obter quanto possível. Quanto a isso, você pode alcançar depende de seus projetos, necessidades e espessura da carteira da sua empresa.

A melhor maneira é não armazenar todas as senhas em qualquer lugar. Isto é conseguido através de funções hash para gerar e hashes de senha loja:

hash("hello") = 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
hash("hbllo") = 58756879c05c68dfac9866712fad6a93f8146f337a69afe7dd238f3364946366

algoritmos de hash são função de mão única. Eles transformar qualquer quantidade de dados em um de comprimento fixo "impressão digital" que não pode ser revertida. Eles também tem a propriedade de que se a entrada muda por até mesmo um pouquinho, o resultante hash é completamente diferente (ver o exemplo acima). este é ótimo para proteger senhas, porque queremos armazenar senhas de uma forma que protege-los mesmo que o arquivo de senhas é comprometida, mas, ao mesmo tempo, é preciso ser capaz de verificar se um a senha do usuário está correto.

nota independente: Nos velhos tempos da internet, quando você clicar em 'Esqueci minha senha' link, sites iria enviar-lhe sua senha de texto simples. Eles foram, provavelmente, armazenar aqueles em algum lugar do banco de dados. Quando hackers ganharam acesso ao seu banco de dados, eles iriam ter acesso a todas as senhas. Uma vez que muitos usuários poderiam usar a mesma senha em vários sites, este foi um problema de segurança enorme. Felizmente, hoje em dia isso não é a prática comum.

Agora vem a pergunta: qual é a melhor maneira de armazenar senhas? Eu consideraria solução este (autenticação e gerenciamento de usuários do stormpath serviço) a mínima bonita um ideal:

  1. O usuário digita as credenciais, e isso é validado contra o hash de senha
  2. hashes de senha são gerados e armazenados, não senhas
  3. Hashes são realizadas várias vezes
  4. clarões são gerados usando um sal gerado aleatoriamente
  5. Hashes são criptografados com uma chave privada
  6. chave privada é armazenada em um lugar fisicamente diferente do que hashes
  7. As chaves privadas estão em uma forma baseada em horário atualizado
  8. hashes criptografados são divididos em pedaços
  9. Estes pedaços são armazenados em locais fisicamente separados

Obviamente você não é o google ou um banco, por isso esta é uma solução exagero para você. Mas então vem a pergunta: Quanto segurança seu projeto requer, quanto tempo e dinheiro você tem?

Para muitas aplicações, embora não seja recomendado, o armazenamento de senha embutida no código pode ser uma solução boa o suficiente. No entanto, facilmente adicionando alguns passos extras de segurança a partir da lista acima, você pode fazer seu aplicativo muito mais seguro.

Por exemplo, vamos supor que o passo 1 não é ser uma solução aceitável para o seu projeto. Você não quer que os usuários digitem a senha de cada vez, ou você não quer mesmo usuários / precisa saber a senha. Ainda você tem um lugar de informação sensível e você quer proteger isto. Você tem uma aplicação simples, não há nenhum servidor para armazenar seus arquivos ou este é demasiado incómodo para o seu projeto. Seu aplicativo é executado em ambientes onde não é possível ter arquivos armazenados de forma segura. Este é um dos piores caso, mas ainda com alguma medida de segurança adicional que você pode ter solução muito mais seguro. Por exemplo, você pode armazenar as informações confidenciais em um arquivo, e você pode criptografar o arquivo. Você pode ter a chave privada de criptografia de disco rígido codificadas no código. Você pode ofuscar o código, para que torná-lo um pouco mais difícil para alguém para quebrá-la. Existem muitas bibliotecas existe para este propósito, veja este link . (Eu quero avisá-lo mais uma vez que este não é 100% segura. Um hacker esperto com o conhecimento certo e ferramentas pode cortar isso. Mas de based em suas exigências e necessidades, isso pode ser uma solução boa o suficiente para você).

Esta questão mostra como armazenar senhas e outros dados em um arquivo criptografado: Java 256-bit AES criptografia baseado em Senha

MD5 é um algoritmo de hash, não um algoritmo de criptografia, em suma o retorno não podem voltar wat u hash, u só pode comparar. Ele deve idealmente ser usado ao armazenar as informações de autenticação do usuário e não usuário e senha db. db username e pwd devem ser criptografados e guardados em um arquivo de configuração, fazer o mínimo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top