domingo, 14 de agosto de 2011

Criptografia segura no PHP


O que é criptografia segura?

Criptografia seguraé o uso de sistemas ou componentes que são considerados altamente resistentes à criptoanálise, o estudo de métodos para decifrar códigos.

Teoricamente falando, se criptografarmos e armazenarmos dados confidenciais em um banco de dados, arquivo, ou qualquer outra coisa, um atacante malicioso não será capaz de descriptografá-los sem saber a chave, uma sequência de números usada para criptografar ou para descriptografar dados. Como podemos provar que o atacante não será capaz de descriptografar os dados?
Infelizmente, a resposta correta é que não podemos ter certeza. Podemos apenas ter um bom nível de segurança usando algoritmos bem testados de criptografia (criptografia segura).
Por exemplo, a cifra ENIGMA, usada na Segunda guerra Mundial como um sistema para criptografar a comunicação entre soldados alemães, hoje não é considerada criptograficamente forte. O DES, um algoritmo padrão do FIST em 1976, que infelizmente ainda é utilizado em muitos sistemas, não é considerado criptograficamente forte mais. Em 1998, a Electronic Frontier Foundation (EFF) construiu uma máquina, o EFF DES cracker, para executar uma pesquisa por força bruta pela key space (o conjunto das possíveis senhas) da encriptação cipher – ou seja, para descriptografar uma mensagem criptografada tentando cada chave possível. O objetivo é provar que a chave DES não é mais segura. Essa máquina era capaz de encontrar a chave de uma mensagem criptografada em menos de um dia, e estamos falando de 1998!
Atualmente, alguns dos algoritmos que podem ser considerados criptograficamente fortes sao: Blowfish, Twofish, Advanced Encryption Standard (AES, Rijndael), 3DES, Serpent, RSA etc. É importante dizer que a segurança de qualquer algoritmo é relacionada à força e ao tamanho da chave, e iremos falar desse ponto a seguir.

Por que devemos usar criptografia segura?

Muitos desenvolvedores, quando têm a necessidade de criptografar alguma informação, tentam implementar suas cifras pessoas usando diferentes abordagens. Na internet, você consegue encontrar várias implementações de cifras domésticas no PHP.
Eu desencorajo fortemente o uso dessas cifras, e vou dizer por quê. Criar uma cifra segura é algo bastante complicado e, se você não for um expert, eu diria que é uma tarefa praticamente impossível. Além disso, estamos falando de criptografia segura, o que significa que mesmo se você for capaz de criar uma nova cifra, você precisa de tempo para provar que ela é segura, compartilhando a implementação do algoritmo na comunidade open source (se você estiver pensando que a segurança da sua cifra está relacionada com a política de não compartilhar seus detalhes, por favor continue a ler este artigo).

Criptografia segura no PHP

O PHP oferece diferentes implementações dos algoritmos de criptografia mais importantes. Em particular, o PHP tem as extensões de criptografia a seguir:
  • Hash
  • mcrypt
  • OpenSSL
A extensão Hash não precisa de bibliotecas externas e é acionada por padrão no PHP 5.1.2. Essa extensão substitui a antiga extensão mhash. Com essa extensão, você pode gerar hashes ou HMAC (Hash-based Message Authentication Code). Ela suporta os algoritmos de geração hash mais comuns usados na criptografia segura. Se você quiser saber quais algoritmos são suportados pelo seu ambiente PHP, pode utilizar a função hash_algos(), que te dá uma lista de todos os algoritmos suportados. Para mais informações sobre essa extensão, veja o manual PHP aqui.
A extensão mcrypt é uma interface para a biblioteca mcrypt, que suporta uma grande variedade de blocos de algoritmos, como DES, 3DES, Blowfish (default), 3-WAY, SAFER-SK64, SAFER-SK128, TWOFISH, TEA, RC2 e GOST nos métodos de encriptação CBC, OFB, CFB e ECB. Essa extensão é a mais utilizada para criptografar dados usando cifras simétricas. Para mais informações sobre ela extensão, veja o manual PHP aqui.
A extensão OpenSSL usa as funções do OpenSSL project para geração e verificação de assinaturas e para lacrar (criptografar) e abrir (descriptografar) dados. Você pode utilizar o OpenSSL para proteger dados usando a criptografia pública de chaves com o algoritmo RSA. Para mais informações sobre essa extensão, veja o manual PHP aqui.

Melhores práticas no PHP

Até agora, discutimos os aspectos gerais da criptografia segura. Agora eu gostaria de te falar quais são as melhores práticas em como usar a criptografia segura no PHP. Aqui você pode encontrar algumas das minhas recomendações:
  • Use algoritmos padrão
Sempre use um algoritmo padrão para criptografar seus dados. Não tente implementar sua cifra doméstica, você irá gastar muito tempo e energia sem conseguir obter uma segurança real. Minha sugestão é usar os melhores algoritmos disponíveis. Exemplos de algoritmos criptograficamente sólidos são:
- algoritmos de chave simétrica: AES, que é um padrão FIST 197 desde 2001;
- algoritmos de chaves públicas: RSA, um algoritmo padrão da industria utilizado em muitos produtos;
- Funções Hash: SHA-x, em que x pode ser 1,256,384, e 512. SHA é um padrão NIST.
  • Espaço da chave
Quando falamos em segurança de uma cifra, o espaço chave é um dos parâmetros mais importantes. Se nenhum design sólido explícito é dado pela cifra, a força do design é igual ao tamanho da chave. Por exemplo, a cifra DES usa uma chave de 56 bits, o que significa que o espaço da chave é de 2^56. Estes números parecem imensos, mas computadores modernos podem suportá-los, e o EFF prova isso com o cracker DES. Então o espaço da chave é muito importante. Para cifras simétricas, eu diria que 128 bits é o tamanho mínimo para uma chave de criptografia forte. Com relação à criptografia de chaves públicas, os experts recomendam um tamanho mínimo de 2048 bits se quisermos proteger nossos dados por 20 anos.
  • Princípio de Kerchoof
Auguste Kerckhoffs foi um linguista alemão e criptógrafo do Higher Commercial Studies em Paris no final do século 19. Ele escreveu, em um artigo famoso do “le Journal des Sciences Militaires”, a seguinte frase, que é considerada o máximo na criptografia moderna:
Um sistema de criptografia deve ser seguro mesmo se tudo que disser respeito ao sistema, exceto a chave, seja de conhecimento público.
Usando a interpretação da Shannon, “O inimigo conhece o sistema”. Na minha opinião, no mundo do software, você somente tem segurança com o uso de algoritmos open source. Se o código-fonte foi testado por milhares de pessoas ao redor do mundo, a probabilidade de encontrar um bug de segurança e consequentemente de consertá-lo é mais alta usando um software open source do que comparada à chance do uso de um software proprietário.
  • Não use rand() ou mt_rand()
Até para este ponto, não tente implementar seu gerador aleatório. Você não pode implementar um gerador de números aleatório seguro usando a função rand() no PHP. Essa função usa a biblioteca libc para gerar números pesudoaleatórios que não são seguros para aplicativos de criptografia. Ela gera números aleatórios usando um método aditivo linear de feedback, com um período curto, que é previsível. Até a função mt_rand() não é segura do ponto de vista da criptografia. Ela uso o algoritmo Mersenne Twister para gerar números pseudoaleatórios. Essa função é melhor que a rand(), porque é mais rápida e produz números pseudoaleatórios com um período maior, mas ainda é um algoritmo determinista, então também é previsível. Para gerar um número aleatório criptograficamente forte no PHP, você tem que usar a função openssl_random_pseudo_bytes() da biblioteca OpenSSL. Essa função está disponível a partir do PHP 5.3. Se você estiver usando uma versão antiga do PHP, pode usar esta implementação:
function secure_rand($length) {
  if(function_exists('openssl_random_pseudo_bytes')) {
    $rnd = openssl_random_pseudo_bytes($length, $strong);
    if($strong === TRUE)
      return $rnd;
  }
  for ($i=0;$i<$length;$i++) {
    $sha= sha1(mt_rand());
    $char= mt_rand(0,30);
    $rnd.= chr(hexdec($sha[$char].$sha[$char+1]));
  }
  return $rnd;
}

Nessa implementação, eu encriptei os outputs da mt_rand() para hash. Esse método aumenta a segurança do Mersenne Twister, mas não tem o mesmo nível de segurança da implementação OpenSSL.
  • Use um valor salt em funções hash
Se você estiver usando uma função hash para proteger os dados, como por exemplo uma senha, concatene os dados com um valor randômico (salt) antes de gerar o hash. Um salt randômico irá proteger seus dados de Dictionary attacks.
  • Tamanho e força de senhas
Não dê a possibilidade para os usuários da sua aplicação web de escolherem senhas bobas e pequenas. Você deve sempre usar uma senha com no mínimo 8 caracteres misturados com números e letras. Você pode usar a biblioteca CrackLib para testar a “força” de uma senha.
  • Não use senhas com texto puro como chave para encriptar
Uma boa prática na criptografia, usando cifras simétricas, é usar um valor hashed como chave de uma cifra. Esse método aumenta a segurança dos dados criptografados ao adicionar maior aleatoriedade. Isso significa que se você quiser gerar uma boa chave para a cifra, você deve usar o hash da senha e usá-lo como a chave do seu algoritmo de criptografia.
  • Use Base64 para codificar dados criptografados
Se você precisar migrar dados criptografados entre sistemas diferentes, como transmitir dados pela internet, é recomendado codificar os dados em Base64. No PHP, você pode usar as funções base64_encode() e base64_decode(). Essa codificação irá garantir que seus dados sejam armazenados corretamente, independentemente do sistema de codificação utilizado no seu ambiente.
É claro que essas são apenas sugestões gerais, e os pontos relacionados ao uso correto da criptografia são mais do isso. Se você estiver interessado em criptografia aplicada, eu fortemente recomendo ler os livros de Bruce Schneier: Applied Cryptography, Practical Cryptography, e Cryptography Engineering. 

Por: Enrico Zimuel
Fonte: http://imasters.com.br 

Nenhum comentário :

Postar um comentário

Total de visualizações de página