Instalação
Artigos
Cursos
Loja
INSTALAÇÃO
ARTIGOS
CURSOS
EBOOKS
DOWNLOADS
LOJA
ARTIGOS
Funções hash em PHP
Quando usar md5, sha1, hash
# Criptografia/Hash Criptografia é a prática e estudo de técnicas que possibilitem uma comunicação segura, ou seja, métodos que possibilitem que apenas as partes interessadas tenham conhecimento de certas informações. Embora na atualidade a criptografia esteja fortemente ligada a computação, ela é usada a centenas de anos. Não existe um manual do modo correto de criptografar mensagens, por isso exitem n métodos e cada um é mais indicado para um contexto. Para termos uma noção da amplitude da criptografia podemos ir desde um dos primeiros sistemas onde as letras de uma mensagem eram trocadas pela letra subsequente do alfabeto até algoritmos mais complexos como o `RSA`.
# Criptografia/Hash + PHP Todas as linguagens de programação oferecem funções que trabalham com algum tipo de criptografia. Cada tipo de criptografia é mais indicado para um tipo de aplicação, as menos complexas normalmente são mais rápidas, no entanto menos seguras. Mesmo não se tratando de algoritmos de criptografia propriamente dito, é possível que você conheça uma dessas funções, elas são as mais conhecidas no `PHP`: * md5 * sha1 * hash As funções `md5` e `sha1` são do tipo mão única, que significa que um conteúdo só pode ser codificado e não o contrário. > `md5` e `sha1` são algoritmos de hash, mas internamente usam tecnologias de criptografia. ## `md5` A função `md5` recebe um parâmetro String e calcula o hash MD5 deste valor. O valor retornado segue as definições do algoritmo [RSA Data Security MD5](http://www.faqs.org/rfcs/rfc1321.html). Independente do tamanho do valor de entrada, a saída será sempre um hash de 32 caracteres. Ou seja, a letra `a` e uma página de texto terão o mesmo tamanho de saída. Esse é o ponto de maior crítica da função `md5`, embora muito improvável dois valores diferentes podem gerar a mesma saída. Não é possível transformar um hash de volta ao seu valor original, mas por se tratar de um algoritmo tão conhecido, exitem tabelas com valores originais e seus valores hash md5 na internet. Por isso é totalmente desaconselhado usar md5 para tarefas críticas, como armazenar senhas. ### Como usar o `md5` O uso da função `md5` é bem direto, basta passar um parâmetro e o será retornado seu hash: ```php "; echo md5('Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus finibus tortor eu fermentum tristique. Ut leo velit, gravida sed bibendum nec, dignissim eget nunc. Phasellus posuere, mauris et porttitor volutpat, magna tortor pellentesque erat, quis iaculis est enim pharetra massa. Pellentesque vitae leo a diam cursus eleifend. Duis vitae est non mauris pellentesque tempor at vel elit. Donec consectetur urna ac sem porttitor semper. Cras rutrum justo lorem, quis porta eros finibus eu. Aenean gravida sem sed elit sollicitudin laoreet. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc pharetra sem sit amet erat elementum, sit amet eleifend enim laoreet. Morbi faucibus libero sed porttitor lobasebortis. Sed sodales pretium orci, in venenatis dui porta vitae.'); ``` As duas chamadas da função retornarão respectivamente os seguintes valores: ``` 0cc175b9c0f1b6a831c399e269772661 1b725c915aaa6ee66fb8a6ba864d119a ``` ## `sha1` A função `sha1` é utilizada exatamente como a função `md5`, ela também recebe uma string como parâmetro e retorna um hash calculado. No entanto desta vez, é retornada uma string com 40 caracteres e o algoritmo usado para calcular o hash é o [US Secure Hash Algorithm 1](http://www.faqs.org/rfcs/rfc3174.html). ### Como usar o `sha1` O uso da função `sha1` é idêntico ao uso da `md5` apenas mudando o nome: ```php "; echo sha1('Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus finibus tortor eu fermentum tristique. Ut leo velit, gravida sed bibendum nec, dignissim eget nunc. Phasellus posuere, mauris et porttitor volutpat, magna tortor pellentesque erat, quis iaculis est enim pharetra massa. Pellentesque vitae leo a diam cursus eleifend. Duis vitae est non mauris pellentesque tempor at vel elit. Donec consectetur urna ac sem porttitor semper. Cras rutrum justo lorem, quis porta eros finibus eu. Aenean gravida sem sed elit sollicitudin laoreet. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc pharetra sem sit amet erat elementum, sit amet eleifend enim laoreet. Morbi faucibus libero sed porttitor lobortis. Sed sodales pretium orci, in venenatis dui porta vitae.'); ``` As duas chamadas da função retornarão respectivamente os seguintes valores: ``` 86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 25f1cf802953b81610039736b1300ac99b6316b2 ``` Pelo fato da função `sha1` retornar um hash com 40 caracteres, torna o fato de dois valores diferentes criarem um mesmo hash menos provável, mas não impossível.
## Performance `md5` x `sha1` Para CPUs modernas calcular o hash `md5` ou `sha1` não é desafio. Por mais complexo e gerar um hash maior a função `sha1` é menos performática, embora a diferença não será percebida em poucas gerações. Dentro de um laço de repetição de 1 milhão de vezes gerando dois hash por iteração obtive os seguintes tempos médios: |Função | Tempo | |--|--| | `md5` | 2.7s | | `sha1` | 3.4s | Embora não seja uma situação real, podemos observa a diferença de performance entre os dois algoritmos. ## `hash` A função hash também é de mão única e retorna o hash calculado de um valor, no entanto nesta função é possível definir qual algoritmo será usado para transformar o valor em hash. Dentro das opções de algoritmos estão opções mais seguras que o `md5` e `sha1`. A lista de algoritmos aceitos pela função hash é: * md2 * md4 * md5 * sha1 * sha256 * sha384 * sha512 * ripemd128 * ripemd160 * ripemd256 * ripemd320 * whirlpool * tiger128,3 * tiger160,3 * tiger192,3 * tiger128,4 * tiger160,4 * tiger192,4 * snefru * gost * adler32 * crc32 * crc32b * haval128,3 * haval160,3 * haval192,3 * haval224,3 * haval256,3 * haval128,4 * haval160,4 * haval192,4 * haval224,4 * haval256,4 * haval128,5 * haval160,5 * haval192,5 * haval224,5 * haval256,5 ### Diferença entre os hash gerados Cada algoritmos gera um hash diferente e com uma determinada quantidade de caracteres, veja a diferença entre eles: Para todos os algoritmos será usada a entrada: > teste123 |Algoritmo|Caracteres| Hash|Tempo para gerar 1 milhão de hash| |--|--|--|--| |md2|32|f04be6186178932020e7efa07d4b183d|4.8s |md4|32|0cf6aea8efdafc9e93853dc1bb220f73|0.7s |md5|32|aa1bf4646de67fd9086cf6c79007026c|0.7s |sha1|40|e0f68134d29dc326d115de4c8fab8700a3c4b002| 1s |sha256|64|| 1.15s |sha384|96|77b2e24f29defef310adfc4170286d15b82ae73448f64019d32b2bc2bca5cec c2cdcdbcca9105514db92abae39a40455| 1.33s |sha512|128|535f56e6447ea0fcf3ef1bf5397066d037e9ebb7fd141068e8de9a23ece8eb6e7 acf46d0e6bbf17edf2ebe6c80405991be53366138e835c3153019f164340619| 1.4s |ripemd128|32|29edb90df848a0c72bc198cc1c9a2d6b| 1.18s |ripemd160|40|90c00d3e2920251cd8d8cbabe1634f4b2938f620| 1.22s |ripemd256|64|2ba16dace1c888d3dc7765ff5b325ed1602e6804cd8e49d388c7bea362e57fc9| 1.05s |ripemd320|80|eb509797a2e7cfbc9c89dc50bf542cb7571f830764d852c50d56508803aae61 9929a7956131f8710| 1.2s |whirlpool|128|1e9f211fac25f8755c1275805ac9211646a042997d0454b352528f1 92ddfde2b97d389e492206ef7b3010786e4e50758dc503442 d64ab22061e2077074541f19|1.35s |tiger128,3|32|72633fbc2f6e7d8867763ddc06065467|0.8s |tiger160,3|40|72633fbc2f6e7d8867763ddc06065467ff9a81f7|0.93s |tiger192,3|48|72633fbc2f6e7d8867763ddc06065467ff9a81f7a61fd76e| 0.9s |tiger128,4|32|31b6aac1919427b2c2f37fde4554d3f6|1s |tiger160,4|40|31b6aac1919427b2c2f37fde4554d3f60490d141|1.12s |tiger192,4|48|31b6aac1919427b2c2f37fde4554d3f60490d1413985ff70|0.92s |snefru|64|60926abb75498ca3ac5c56a84925fb474c502c8ed4424706f037b133184b4e4e|3.5s |gost|64|d31ec716aab43f758aab37822991311e8a07da7861f03a665842ab2ed31f2913|2.9s |adler32|8|0e1f02bc|0.7s |crc32|8|6de1b1ea| 0.6s |crc32b|8|6ea3a7d0| 0.6s |haval128,3|32|07cbe29488f06c735f6aabd489dec44c|1.4s |haval160,3|40|fab7b8f065b99de48571fb5895fe649cf7e1ece5|1.4s |haval192,3|48|87934037f607174955ed027851c563460f63419c56b0e2f1|1.41s |haval224,3|56|98329dd52d13bb31bcab193f80d03f4abe44e606635a4c7afdf88cee|1,31s |haval256,3|64|f1bd6250d1bcdd6bb4088aef70d9648c095e3570068ca4d375357b573169d6db|1.28s |haval128,4|32|833919adffd05026f57660b4090c11a8|1.6s |haval160,4|40|2dac1a9073160e78b7b94e5ed1586338a2c6576c|1.72s |haval192,4|48|af0639d5b746e5e851a3f1919e22854f872518872f107065|2s |haval224,4|56|e37dcecdb1b7a6d6a45808745ab9246722e6d03ebe18cff3056deca9|1.82s |haval256,4|64|62fa99060a89f69fec343f350ecfbe16ad6de92922a6e5355f5aa1e6fe782223|1.9s |haval128,5|32|bff0e77fd6452b5f4100152c13f12c85|1.8s |haval160,5|40|f23a2e57aab5cf4b6c4bc525695b3f9e6a410f0e|1.75s |haval192,5|48|0f0db7949a07deaf6f9f69b625204e2a1dd8dc7f04a5871a|1.74s |haval224,5|56|70f21256d16832b571216cf450210991790f12af3f187db082b7bd78|2.2s |haval256,5|64|580e7a2987849b7d4de101f56a2645f2afd581add2f5487874f2c003e3780809|1.9s ## Adicionar sal nos hash Como vimos nos algoritmos e funções que calculam hash acima, é possível que dois valores diferentes gerem um mesmo hash. Outro problema é que embora não seja possível reverter um hash para o valor original existem tabelas disponíveis na internet que ligam o valor original ao seu hash. Uma técnica que pode solucionar esses problemas é a adição de um sal no momento de gerar um hash, também conhecido com *salt*. Um sal nada mais é, do que informação adicional ao valor a ser passado na função de hash que aumentam significativamente a segurança dos hash. Um exemplo de aplicação seria, no momento de armazenar hash de senhas no banco de dados. É possível adicionar um sal na senha, que somente o desenvolvedor conheça ou até mesmo usar alguma informação do nome do usuário. Desta maneira mesmo duas pessoas com a mesma senha não terão o mesmo hash.
COMENTE SOBRE