Estou criando um aplicativo que armazena senhas, que o usuário pode recuperar e visualizar. As senhas são para um dispositivo de hardware, portanto, a verificação de hashes está fora de questão.
O que eu preciso saber é:
Como criptografar e descriptografar uma senha no PHP?
Qual é o algoritmo mais seguro para criptografar as senhas?
Onde guardo a chave privada?
Em vez de armazenar a chave privada, é uma boa ideia exigir que os usuários insiram a chave privada sempre que precisarem de uma senha descriptografada? (Os usuários deste aplicativo podem ser confiáveis)
De que maneiras a senha pode ser roubada e descriptografada? Do que eu preciso estar ciente?
php
security
encryption
passwords
HyderA
fonte
fonte
Respostas:
Pessoalmente, eu usaria
mcrypt
como outros postados. Mas há muito mais a ser observado ...Como criptografar e descriptografar uma senha no PHP?
Veja abaixo uma classe forte que cuida de tudo para você:
Qual é o algoritmo mais seguro para criptografar as senhas?
mais seguro ? qualquer um deles. O método mais seguro para criptografar é proteger contra vulnerabilidades de divulgação de informações (XSS, inclusão remota etc.). Se sair, o invasor pode eventualmente quebrar a criptografia (nenhuma criptografia é 100% reversível sem a chave - como @NullUserException indica que isso não é totalmente verdade. Existem alguns esquemas de criptografia impossíveis de decifrar, como o OneTimePad ) .
Onde guardo a chave privada?
O que eu faria é usar 3 chaves. Um é fornecido pelo usuário, um é específico ao aplicativo e o outro é específico ao usuário (como um sal). A chave específica do aplicativo pode ser armazenada em qualquer lugar (em um arquivo de configuração fora da raiz da web, em uma variável ambiental, etc.). O específico do usuário seria armazenado em uma coluna no banco de dados próximo à senha criptografada. O usuário fornecido não seria armazenado. Então, você faria algo assim:
O benefício é que qualquer uma das duas chaves pode ser comprometida sem que os dados sejam comprometidos. Se houver um ataque de injeção SQL, eles podem obter o
$userKey
, mas não o outro 2. Se houver uma exploração do servidor local, eles podem obter$userKey
e$serverKey
, mas não o terceiro$userSuppliedKey
. Se eles baterem no usuário com uma chave inglesa, poderão obter o$userSuppliedKey
, mas não os outros 2 (mas, novamente, se o usuário for espancado com uma chave inglesa, você será tarde demais).Em vez de armazenar a chave privada, é uma boa ideia exigir que os usuários insiram a chave privada sempre que precisarem de uma senha descriptografada? (Os usuários deste aplicativo podem ser confiáveis)
Absolutamente. De fato, essa é a única maneira de fazê-lo. Caso contrário, você precisará armazenar uma versão não criptografada em um formato de armazenamento durável (memória compartilhada, como APC ou memcached, ou em um arquivo de sessão). Isso está se expondo a compromissos adicionais. Nunca armazene a versão não criptografada da senha em nada, exceto em uma variável local.
De que maneiras a senha pode ser roubada e descriptografada? Do que eu preciso estar ciente?
Qualquer forma de comprometimento de seus sistemas permitirá que eles visualizem dados criptografados. Se eles puderem injetar código ou acessar o sistema de arquivos, poderão visualizar os dados descriptografados (já que podem editar os arquivos que descriptografam os dados). Qualquer forma de ataque Replay ou MITM também lhes dará acesso total às chaves envolvidas. Farejar o tráfego HTTP bruto também fornecerá as chaves.
Use SSL para todo o tráfego. E verifique se nada no servidor possui algum tipo de vulnerabilidade (CSRF, XSS, Injeção de SQL, Escalação de Privilégios, Execução Remota de Código, etc.).
Edit: Aqui está uma implementação de classe PHP de um método de criptografia forte:
Note que eu estou usando uma função adicionado no PHP 5.6:
hash_equals
. Se você estiver com menos de 5,6, poderá usar esta função substituta que implementa uma função de comparação com tempo seguro usando a verificação dupla do HMAC :Uso:
Então, para descriptografar:
Observe que eu usei
$e2
a segunda vez para mostrar que diferentes instâncias ainda decifrariam os dados corretamente.Agora, como funciona / por que usá-lo em outra solução:
Chaves
As chaves não são usadas diretamente. Em vez disso, a chave é esticada por uma derivação PBKDF2 padrão.
A chave usada para criptografia é exclusiva para cada bloco de texto criptografado. A chave fornecida torna-se, portanto, uma "chave mestra". Essa classe, portanto, fornece rotação de chaves para chaves de cifra e autenticação.
NOTA IMPORTANTE , o
$rounds
parâmetro está configurado para chaves aleatórias verdadeiras com força suficiente (128 bits de aleatório Criptograficamente seguro no mínimo). Se você for usar uma senha ou chave não aleatória (ou menos aleatória que 128 bits de CS aleatória), deverá aumentar este parâmetro. Eu sugeriria um mínimo de 10000 para senhas (quanto mais você puder pagar, melhor, mas isso aumentará o tempo de execução) ...Integridade de dados
Criptografia:
MCRYPT_BLOWFISH
ou deMCRYPT_RIJNDAEL_128
códigos eMCRYPT_MODE_CBC
para o modo. É forte o suficiente e ainda bastante rápido (um ciclo de criptografia e descriptografia leva cerca de 1/2 segundo na minha máquina).Agora, como no ponto 3 da primeira lista, o que isso daria a você é uma função como esta:
Você pode esticá-lo na
makeKey()
função, mas como ele será expandido mais tarde, não há realmente um grande ponto em fazê-lo.Quanto ao tamanho do armazenamento, isso depende do texto sem formatação. O Blowfish usa um tamanho de bloco de 8 bytes, então você terá:
Portanto, para uma fonte de dados de 16 caracteres, haverá 16 caracteres a serem criptografados. Isso significa que o tamanho real dos dados criptografados é de 16 bytes devido ao preenchimento. Em seguida, adicione 16 bytes para o salt e 64 bytes para o hmac e o tamanho total armazenado é 96 bytes. Portanto, há no máximo uma sobrecarga de 80 caracteres e, na pior, uma sobrecarga de 87 caracteres ...
Espero que ajude ...
Nota: 12/11/12: Acabei de atualizar esta classe com um método de criptografia MUITO melhor, usando chaves derivadas melhores e corrigindo a geração MAC ...
fonte
-64
s a-128
ajudou (de modo a obter$enc = substr($data, 128, -128)
e$mac = substr($data, -128);
Como criptografar e descriptografar uma senha no PHP? Implementando um dos muitos algoritmos de criptografia. (ou usando uma das muitas bibliotecas)
Qual é o algoritmo mais seguro para criptografar as senhas? Existem vários algoritmos diferentes, nenhum dos quais é 100% seguro. Mas muitos deles são seguros o suficiente para o comércio e até para fins militares
Onde guardo a chave privada? Se você decidiu implementar o algoritmo de criptografia de chave pública (por exemplo, RSA), não armazena chave privada. usuário tem chave privada. seu sistema possui uma chave pública que pode ser armazenada em qualquer lugar que você desejar.
Em vez de armazenar a chave privada, é uma boa ideia exigir que os usuários insiram a chave privada sempre que precisarem de uma senha descriptografada? (Os usuários deste aplicativo podem ser confiáveis) Bem, se o usuário puder se lembrar de números primos ridiculamente longos, então - sim, por que não. Mas geralmente você precisa criar o sistema que permitirá ao usuário armazenar sua chave em algum lugar.
De que maneiras a senha pode ser roubada e descriptografada? Do que eu preciso estar ciente? Isso depende do algoritmo usado. No entanto, sempre verifique se você não envia uma senha não criptografada para ou do usuário. Criptografe / descriptografe no lado do cliente ou use https (ou outro meio criptográfico do usuário para proteger a conexão entre servidor e cliente).
No entanto, se tudo o que você precisa é armazenar senhas de maneira criptografada, sugiro que você use uma cifra XOR simples. O principal problema desse algoritmo é que ele pode ser facilmente quebrado pela análise de frequência. No entanto, como geralmente as senhas não são feitas de longos parágrafos do texto em inglês, acho que você não deve se preocupar com isso. O segundo problema com o XOR Cipher é que, se você tiver uma mensagem no formato criptografado e descriptografado, poderá descobrir facilmente a senha com a qual foi criptografada. Novamente, não é um grande problema no seu caso, pois afeta apenas o usuário que já foi comprometido por outros meios.
fonte
O exemplo do manual é ligeiramente editado para este exemplo):
Você usaria mcrypt_decrypt para descriptografar sua senha.
O melhor algoritmo é bastante subjetivo - pergunte a 5 pessoas, obtenha 5 respostas. Pessoalmente, se o padrão (Blowfish) não for bom o suficiente para você, você provavelmente terá problemas maiores!
Dado que o PHP é necessário para criptografar - não tendo certeza de que você pode ocultá-lo em qualquer lugar - dê boas-vindas aos comentários sobre isso. As melhores práticas de codificação PHP padrão se aplicam, é claro!
Dado que a chave de criptografia estará no seu código de qualquer maneira, não tenha certeza do que você ganhará, desde que o restante do seu aplicativo seja seguro.
Obviamente, se a senha criptografada e a chave de criptografia forem roubadas, o jogo termina.
Eu colocaria um piloto na minha resposta - não sou especialista em criptografia PHP, mas acho que o que respondi é uma prática padrão - congratulo-me com comentários que outros possam ter.
fonte
$pass = $text
. Acho que ele mudou isso para atender à pergunta e não percebeu a segunda ocorrência.MCRYPT_MODE_ECB
não usa um IV. Em segundo lugar, se o fizesse, seria necessário para armazenar o IV como você não pode descriptografar os dados sem ele ...Muitos usuários sugeriram o uso do mcrypt ... o que é correto, mas eu gosto de ir um pouco mais longe para torná-lo facilmente armazenado e transferido (já que às vezes os valores criptografados podem dificultar o envio usando outras tecnologias como curl ou json) .
Depois de criptografar com sucesso usando mcrypt, execute-o através do base64_encode e converta-o em código hexadecimal. Uma vez no código hexadecimal, é fácil transferir de várias maneiras.
E do outro lado:
fonte
Eu sugeriria apenas a criptografia de chave pública se você quiser definir a senha de um usuário sem a interação (isso pode ser útil para redefinições e senhas compartilhadas).
Chave pública
openssl_public_encrypt
eopenssl_private_decrypt
Simétrico
Ambos
4
. Sim - os usuários precisariam digitar a senha do aplicativo toda vez, mas armazená-la na sessão geraria outros problemas5
.fonte
openssl_private_decrypt()
.Eu tentei algo parecido com isto, mas observe que não sou criptografador nem tenho profundo conhecimento sobre
php
ou qualquer linguagem de programação. É apenas uma ideia. Minha idéia é armazenarkey
em algum arquivo oudatabase
(ou inserir manualmente) que (local) não possa ser facilmente previsto (e, é claro, qualquer coisa será descriptografada algum dia, o conceito é aumentar o tempo de descriptografia) e criptografar informações confidenciais.Por favor, note que é apenas um conceito. Qualquer melhoria neste código seria altamente apreciável.
fonte
Eh? Eu não entendo Você quer dizer apenas que a senha deve ser recuperável?
Como outros já disseram, a extensão mcrypt fornece acesso a muitas funções criptográficas - no entanto, você está convidando seus usuários a colocar todos os ovos em uma cesta - uma que será potencialmente um alvo para os invasores - e se você nem sabe como começar a resolver o problema, você estará fazendo um desserviço aos usuários. Você não está em posição de entender como proteger os dados.
A maioria das vulnerabilidades de segurança ocorre não porque o algoritmo subjacente é defeituoso ou inseguro - mas devido a problemas com a maneira como o algoritmo é usado no código do aplicativo.
Dito isto, é possível construir um sistema razoavelmente seguro.
Você deve considerar a criptografia assimétrica apenas se precisar de um usuário para criar uma mensagem segura que seja legível por outro usuário (específico). A razão é que é computacionalmente caro. Se você deseja apenas fornecer um repositório para que os usuários insiram e recuperem seus próprios dados, a criptografia simétrica é adequada.
Se, no entanto, você armazenar a chave para descriptografar a mensagem no mesmo local da mensagem criptografada (ou onde a mensagem criptografada está armazenada), o sistema não estará seguro. Use o mesmo token para autenticar o usuário e para a chave de descriptografia (ou, no caso de criptografia assimétrica, use o token como a senha da chave privada). Como você precisará armazenar o token no servidor em que a descriptografia ocorre pelo menos temporariamente, considere usar um substrato de armazenamento de sessão não pesquisável ou passar o token diretamente para um daemon associado à sessão que armazenaria o token na memória e execute a descriptografia de mensagens sob demanda.
fonte
Use password_hash e password_verify
E para descriptografar:
fonte