Como você poderia implementar um sistema estático seguro credenciais de login em Java?

StackOverflow https://stackoverflow.com/questions/103203

Pergunta

Recentemente, tivemos uma auditoria de segurança e expôs várias fraquezas nos sistemas que estão em vigor aqui. Uma das tarefas que resultaram de que é que precisamos atualizar nosso sistema de credenciais parceiros torná-lo mais seguro.

A maneira "velha" de fazer as coisas era gerar um (mau) senha, dá-lo ao parceiro com um ID e, em seguida, eles iriam enviar esse ID e uma cópia codificado Base 64 desse senha no com toda a sua XML pedidos por HTTPS. Nós então decodificá-los e validá-los.

Essas senhas não vai mudar (porque então nossos parceiros teria que fazer a codificação mudanças / config para mudá-los e coordenar expirações de senha com centenas de parceiros para vários ambientes seria um pesadelo) e eles não têm de ser introduzidos por um humano ou legível. Estou aberto a mudar este se houver uma implementação melhor, mas ainda relativamente simples para os nossos parceiros.

Basicamente, ele se resume a duas coisas:. Preciso de um sistema e Java geração de senha mais segura para garantir que eles são transmitidos de forma segura

Eu encontrei alguns geradores de senha enrolados à mão, mas nada que realmente se destacou como uma maneira padrão de fazer isso (talvez por uma boa razão). Também pode haver uma maneira mais segura para transmiti-los do que simples codificação de base 64 sobre https.

O que você faria para o gerador de senha e você acha que o método de transmissão no local é bastante seguro para ele?

Edit: O XML vem em uma mensagem SOAP e as credenciais são no cabeçalho não no próprio XML. Além disso, como as senhas são um one-off operação para cada parceiro quando configurá-los não estamos muito preocupados com a eficiência do gerador.

Foi útil?

Solução

Senha Geração

Quanto codifica uma senha para a transmissão, a única codificação que vai realmente adicionar segurança é criptografia. Usando Base-64 ou hexadecimal não é para segurança, mas apenas para ser capaz de incluí-lo em um formato de texto como XML.

A entropia é usado para medir a qualidade de senha. Assim, a escolha de cada bit com um "coin-flip" aleatório vai lhe dar a senha de melhor qualidade. Você gostaria senhas para ser tão forte quanto outras chaves criptográficas, por isso eu recomendo um mínimo de 128 bits de entropia.

Existem dois métodos fáceis, dependendo de como você deseja codificar a senha como texto (que realmente não importa do ponto de vista de segurança).

Para Base-64 , use algo como isto:

  SecureRandom rnd = new SecureRandom();
  /* Byte array length is multiple of LCM(log2(64), 8) / 8 = 3. */
  byte[] password = new byte[18];
  rnd.nextBytes(password);
  String encoded = Base64.encode(password);

A seguir não exige que você para vir acima com um codificador de Base-64. A codificação resultante não é tão compactos (26 caracteres em vez de 24) e a palavra-passe não tem tanto entropia. (Mas 130 bits já é muito, comparável a uma senha de pelo menos 30 caracteres escolhidos por um ser humano.)

SecureRandom rnd = new SecureRandom();
/* Bit length is multiple of log2(32) = 5. */
String encoded = new BigInteger(130, rnd).toString(32); 

Criar nova SecureRandom objetos é computacionalmente caro, por isso, se você está indo para gerar senhas com freqüência, você pode querer criar uma instância e mantê-lo ao redor.

Uma abordagem melhor

Incorporação a senha no próprio XML parece ser um erro.

Em primeiro lugar, parece que você gostaria de autenticar o remetente antes de processar quaisquer documentos que você enviar. Suponha que eu odeio suas entranhas, e começar a enviar-lhe os arquivos XML gigantes para executar um ataque de negação de serviço. Você quer ter de analisar o XML apenas para descobrir que eu não sou um parceiro legítimo? Não seria melhor se o servlet acaba de rejeitar solicitações de usuários não autenticados na frente?

Em segundo lugar, as senhas de seus parceiros legítimos foram protegidas durante a transmissão por HTTPS, mas agora eles estão provavelmente armazenadas "em claro" em seu lugar sistema. Isso é ruim de segurança.

Uma abordagem melhor seria parceiros autenticar quando eles lhe enviar um documento com credenciais nos cabeçalhos de solicitação HTTP. Se você permitir que apenas HTTPS, você pode tirar a senha fora do documento completamente e colocá-lo em um HTTP cabeçalho de autenticação "Basic" em vez. É protegido por SSL durante a transmissão, e não armazenados em seu sistema em claro (você só armazenar um hash unidirecional para fins de autenticação).

HTTP autenticação básica é simples, amplamente apoiada, e será muito mais fácil para você e seus parceiros de implementar do que certificados de cliente SSL.

Protegendo o conteúdo do Documento

Se o conteúdo dos próprios documentos é sensível, eles realmente devem ser criptografados pelo remetente, e armazenados por você em sua forma criptografada. A melhor maneira de fazer isso é com criptografia de chave pública, mas isso seria um assunto para outra questão.

Outras dicas

Não foi possível usar SSL Chaves para autenticação?

Eu estou claro por transmitir as senhas mais de SSL - via HTTPS - está sendo considerado "inseguro" por sua equipe de auditoria. Então, quando você pedir duas coisas, parece que o segundo - a garantia de que as senhas estão sendo transmitidos de forma segura -. Já está sendo tratado muito bem

Quanto ao primeiro, teríamos de saber o que acontece com a auditoria exposto suas senhas tão inseguro ...

Eu abandonar a abordagem senha toda e começar a usar certificados de cliente, permitindo uma conexão SSL autenticado 2 lateral.

Você tem que gerar e assinar certificados individuais para cada cliente. No handshake SSL, você solicitar o certificado do cliente e verificá-la. Se ele falhar, as extremidades de conexão com um código de estado 401.

Os certificados podem ser revogada a qualquer momento, ser seu lado, permitindo facilmente desconectar ex-clientes.

Uma vez que tudo isso acontece no aperto de mão antes da comunicação, é não é possível para inundar o servidor com dados.

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