Pergunta

Uma vez que esta questão é bastante popular, eu pensei que seria útil para dar-lhe uma atualização.

Deixe-me enfatizar a resposta correta como dado por ávidos a esta pergunta:

Você não deve armazenar quaisquer dados que as necessidades de criptografia no seu cookie. Em vez disso, armazenar um bom tamanho (128 bits / 16 bytes) chave aleatória no cookie e armazenar as informações que deseja manter seguro no servidor, identificado pela chave do cookie.



Eu estou procurando informações sobre 'o melhor' algoritmo de criptografia para criptografar cookies.

Eu hava os seguintes requisitos:

  • Deve ser rápido
    criptografar e descriptografar os dados será feito para (quase) todos os pedidos

  • Ele vai operar em pequenos conjuntos de dados, tipicamente cordas de cerca de 100 caracteres ou menos

  • Deve ser seguro, mas não é como se estivéssemos proteger transações bancárias

  • Precisamos ser capaz de decifrar a informação de modo SHA1 e similares estão fora.

Agora eu li que Blowfish é rápido e seguro, e eu li que AES é rápido e seguro. Com Blowfish tendo um tamanho de bloco mais pequeno.

Eu acho que ambos os algoritmos fornecer mais do que a segurança adequada? por isso a velocidade, então, tornar-se o fator decisivo. Mas eu realmente não tenho idéia se os algoritmos são adequados para pequena cadeia de caracteres e se há algoritmo talvez mais adequado para criptografar cookies.

Então, minha pergunta é:
O algoritmo de criptografia é melhor para criptografar dados do cookie?

Atualizar
Para ser mais preciso, queremos criptografar 2 cookie:. Um com informações da sessão e outro com 'Lembra-te de Mim' informações

A plataforma é PHP como apache módulo sobre Linux em um VPS.

Update 2
Concordo com cletus que armazenar qualquer informação em um cookie é inseguro.

No entanto, temos um requisito para implementar uma 'Lembra-te de Mim' recurso. A maneira aceitável de fazer isso é através da criação de um cookie. Se os presentes de clientes este cookie, ele ou ela é permitido o acesso ao sistema com (quase) igualdade de direitos, como se ele / ela apresentou a combinação de senha nome de usuário válido.

Assim, pelo menos, quer para criptografar todos os dados no cookie de modo que:
a) usuários mal-intencionados não pode ler o seu conteúdo,
b) usuários mal-intencionados não pode fabricar seu próprio cookie ou adulteração com ele.

(Todos os dados de biscoitos é higienizado e verificada a sua validade antes de fazer qualquer coisa com ele, mas isso é outra história)

O cookie de sessão contém um sessionId / timestamp nada mais. Ele provavelmente poderia ser usada sem criptografia, mas não vejo nenhum mal em criptografando-? (Diferente de tempo de computação).

Assim, dado que temos de armazenar alguns dados sobre em um cookie, o que é a melhor maneira de criptografá-lo?

Update 3
As respostas a esta pergunta me fez reconsiderar a abordagem escolhida. I podem realmente fazer o mesmo, sem a necessidade de criptografia. Em vez de criptografar os dados, eu só deve enviar dados que não tem sentido sem ele do contexto e não pode ser adivinhada .

No entanto, eu também estou em uma perda:
Eu pensei que a criptografia habilitado nos enviar dados para fora para o BigBadWorld ™, e ainda ser (bastante) a certeza de que ninguém sabia ler nem mexer com o que ...
Não era que todo o ponto de criptografia?

Mas as reações abaixo impulso na direção: Não criptografia confiança para realizar a segurança.

O que estou ausente ??

Foi útil?

Solução

Sem verdadeira razão para não ir com AES com 256 bits. Certifique-se de usar isso em modo CBC e PKCS # 7 preenchimento. Como você disse, rápido e seguro.

Eu li (não testado) que Blowfish podem ser marginalmente mais rápido ... No entanto Blowfish tem uma grande desvantagem de longa data de instalação, o que tornaria ruim para a sua situação. Além disso, a AES é mais "comprovada".

Isso pressupõe que ele realmente é necessária para criptografar simetricamente seus dados de cookies. Como outros, ele realmente não deve ser necessário, e existem apenas alguns casos extremos, onde não há outra escolha senão fazê-lo. Comumente, seria melhor servi-lo para mudar o design, e voltar para ambos identificadores de sessão aleatórias, ou se necessárias hashes unidirecionais (usando SHA-256).
No seu caso, além do identificador de sessão "regular" aleatório, o problema é o "Remember Me" recurso - este também deve ser implementado como quer:

  • um número aleatório de comprimento, armazenados no banco de dados e mapeado para uma conta de usuário;
  • ou um hash codificado (por exemplo HMAC) contendo, por exemplo, o nome de usuário, timestamp, mebbe um sal, e uma chave de servidor segredo. Esta lata de server-side claro que todos ser verificada ...

Parece que nós começamos um pouco fora tema do seu original, pergunta específica - e mudou a base da sua pergunta mudando o desenho ....
Então, enquanto nós estamos fazendo isso, eu também altamente recomendável CONTRA este recurso de persistente "Remember Me", por várias razões, o maior entre eles:

  • torna muito mais provável que alguém pode roubar o usuário se lembrar chave, permitindo-lhes para falsificar a identidade do usuário (e então, provavelmente, mudar a sua senha);
  • CSRF - Cross site Request Forgery . Seu recurso permitirá efetivamente um invasor anônimo para causar desconhecendo usuários poderão enviar solicitações "autenticados" para a sua aplicação, mesmo sem ser realmente logado.

Outras dicas

Esta é tocar em duas questões separadas.

Em primeiro lugar, seqüestro de sessão . Este é o lugar onde um terceiro descobre, digamos, um cookie de autenticação e ganha acesso a outra pessoa detalhes.

Em segundo lugar, existe segurança de dados sessão . Com isto quero dizer que você armazenar dados no cookie (como o nome de usuário). Isso não é uma boa ideia. Qualquer desses dados é fundamentalmente não confiável assim como dados de formulário HTML não é confiável (independentemente do que a validação Javascript e / ou restrições de comprimento HTML que você usa, se houver) porque o cliente é livre para apresentar o que eles querem.

Você vai encontrar muitas vezes as pessoas (com razão) defendendo higienização HTML formulário de dados, mas os dados do cookie será cegamente aceito em valor de face. Grande erro. Na verdade, eu nunca armazena qualquer informação no cookie. Eu vê-lo como uma chave de sessão e isso é tudo.

Se você pretende armazenar dados em um cookie eu recomendo fortemente que você reconsidere.

A criptografia de dados não tornar a informação mais fidedigna, porque a criptografia simétrica é suscetível ao ataque de força bruta. Obviamente AES-256 é melhor do que, digamos, DES (heh), mas 256 bits de segurança não significa necessariamente tanto quanto você acha que ele faz.

Por um lado, os sais são tipicamente geradas de acordo com um algoritmo ou são de outra forma susceptíveis ao ataque.

Por outro lado, dados cookie é um excelente candidato para berço ataques. Se for conhecida ou suspeita de que um nome de usuário está nos dados criptografados será Ei, tem o seu berço.

Isso nos traz de volta ao primeiro ponto:. Seqüestro

Deve ser salientado que na partilha de hospedagem de ambientes em PHP (como um exemplo) seus dados sessão é simplesmente armazenado no sistema de arquivos e pode ser lido por qualquer outra pessoa no mesmo hospedeiro, embora eles não necessariamente sabe qual site ele é para. Por isso, nunca armazenar senhas em texto puro, números de cartão de crédito, extensos dados pessoais ou qualquer coisa que poderiam ser considerados como sensíveis em dados da sessão em tais ambientes sem alguma forma de criptografia ou, ainda melhor, apenas armazenar uma chave na sessão e armazenar o sensível real dados em um banco de dados.

Nota:. o acima não é exclusivo para PHP

Mas isso de criptografia no servidor.

Agora, você poderia argumentar que a criptografia de uma sessão com alguns dados extra irá torná-lo mais seguro de seqüestro. Um exemplo comum é o endereço IP do usuário. O problema é que muitas pessoas usam o mesmo PC / laptop em muitos locais diferentes (por exemplo Wifi hotspots, trabalho, casa). Também muitos ambientes usará uma variedade de endereços IP como o endereço de origem, particularmente em ambientes corporativos.

Você também pode usar o agente de usuário, mas isso é adivinhação.

Então, realmente, tanto quanto eu posso dizer, não há nenhuma razão real para utilizar a encriptação de cookies em tudo. Eu nunca achei que houvesse, mas, à luz desta pergunta que eu fui à procura de ser provado certo ou errado. Eu encontrei alguns fios sobre as pessoas sugerindo formas de dados de cookies criptografar, transparente fazê-lo com os módulos do Apache, e assim por diante, mas estes tudo parecia motivado pela proteção de dados armazenados em um cookie (que IMHO você não deve fazer).

Eu ainda tenho que ver um argumento de segurança para criptografar um cookie que representa nada mais do que uma chave de sessão.

Eu ficaria feliz em ser provado errado se alguém pode apontar algo em contrário.

Aviso de segurança : Estas duas funções são não seguro. Eles estão usando BCE modo e deixar de autenticar o texto cifrado . Consulte esta resposta para um caminho melhor.

Para aqueles leitura através querer usar este método em scripts PHP. Aqui está um exemplo de trabalho usando 256 bits Rijndael (não AES).

function encrypt($text, $salt) 
{ 
    return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $salt, $text, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND)))); 
} 

function decrypt($text, $salt) 
{ 
    return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $salt, base64_decode($text), MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND))); 
}

Depois de salvar o cookie

setcookie("PHPSESSION", encrypt('thecookiedata', 'longsecretsalt'));

e ler na página seguinte:

$data = decrypt($_COOKIE['PHPSESSION'], 'longsecretsalt');

Você pode conseguir o que deseja com segurança usando AES no modo EAX. O texto cifrado vai ser maior do que o texto simples; isso é normal para criptografia segura.

O atacante vai, naturalmente, saber o comprimento do seu texto original do texto cifrado, mas eles não devem ser capazes de determinar que qualquer outra coisa.

Gerar chaves AES de forma aleatória.

Certifique-se e usar um novo nonce para cada criptografia, e use o campo "dados associados" para garantir que uma coisa que você criptografada para uma finalidade não é apresentado como sendo para o outro (assim que as coisas como o nome de usuário e nome de cookie poderia ir lá)

as reações abaixo impulso na direção: Do Não criptografia confiança para realizar segurança.

Mais "se você não for um perito de criptografia que você vai subestimar o quão fácil é para obter errado". Por exemplo, AFAICT ninguém mais neste segmento tem discutido encadeamento modos ou a integridade da mensagem, que cobre dois erros de principiante comum.

Rápido, cookies criptografados com Libsodium

Se você precisar rápido, seguro biscoitos criptografados em PHP, confira como Halite implementa. Halite depende a extensão libsodium PECL para fornecer criptografia segura.

<?php
use \ParagonIE\Halite\Cookie;
use \ParagonIE\Halite\Symmetric\Key;
use \ParagonIE\Halite\Symmetric\SecretKey;

// You can also use Key::deriveFromPassword($password, $salt, Key::CRYPTO_SECRETBOX);
$encryption_key = new SecretKey($some_constant_32byte_string_here);

$cookie = new Cookie($encryption_key);

$cookie->store('index', $any_value);
$some_value = $cookie->fetch('other_index');

Se você não pode instalar extensões PECL, pergunte ao seu administrador de sistema ou provedor de hospedagem para fazer isso por você. Se eles se recusarem, você ainda tem opções.


seguras e criptografadas cookies em PHP, Segure o sal Por favor

As outras respostas instruí-lo para criptografar seus dados com o OpenSSL ou mcrypt, mas eles estão faltando uma etapa crucial. Se você quiser dados de forma segura criptografar em PHP , você deve autenticar suas mensagens.

Usando a extensão OpenSSL, o processo você precisará seguir parecido com este:


Preâmbulo

  • (Antes mesmo de pensar em criptografia) Gerar uma de 128 bits, 192 bits ou 256 bits seqüência aleatória. Esta será a sua chave mestre .

    Não use uma senha legível Se você, por alguma razão, deve usar uma senha legível, pergunte Cryptography SE para orientação.

    Se você precisar de uma atenção especial, serviços de consultoria meu empregador ofertas tecnologia , incluindo o desenvolvimento de criptografia recursos.

Criptografia

  1. Gerar um aleatória vetor de inicialização (IV) ou de uso único. por exemplo. random_bytes(openssl_cipher_iv_length('aes-256-cbc'))
  2. HKDF ou um algoritmo semelhante para dividir sua chave mestra em duas chaves:
    1. Uma chave de criptografia ($eKey)
    2. Uma chave de autenticação ($aKey)
  3. Criptografar sua seqüência com openssl_encrypt() com o seu IV e um modate apropriado (por exemplo aes-256-ctr) usando sua chave de criptografia ($eKey) a partir do passo 2.
  4. Compute um tag de autenticação do seu texto cifrado a partir do passo 3, utilizando uma função hash com chave tais como HMAC-SHA256. por exemplo. hash_hmac('sha256', $iv.$ciphertext, $aKey). É muito importante para autenticar depois de criptografia e para encapsular o IV / nonce também.
  5. Pacote a marca de autenticação, IV ou de uso único, em conjunto e texto cifrado e codificar opcionalmente com bin2hex() ou base64_encode(). (Aviso:. Esta abordagem força informações de vazamento de cache-tempo)

descriptografia

  1. Split sua chave, como por etapa 2 em criptografia. Precisamos das mesmas duas teclas durante a descriptografia!
  2. (Opcionalmente, e descodificar) descompactar o MAC, IV, e de texto cifrado a partir da mensagem embalado.
  3. Verifique a etiqueta de autenticação recalculando o HMAC do IV / nonce e texto cifrado com o HMAC fornecido pelo usuário usando hash_equals() .
  4. Se e somente se a etapa 3 passes, descriptografar o texto cifrado usando $eKey.

Se você quiser ver como este todos os olhares juntos, consulte esta resposta que tem código de exemplo .

Se isso soa como muito trabalho, uso defuse / php-encryption ou zend-crypt e chamá-lo um dia.


Remember Me cookies

No entanto, temos um requisito para implementar uma 'Lembra-te de Mim' recurso. Tele aceitou maneira de fazer isso é através da criação de um cookie. Se os presentes de clientes este cookie, ele ou ela é permitido o acesso ao sistema com (quase) igualdade de direitos, como se ele / ela apresentou a combinação de senha nome de usuário válido.

A criptografia não é realmente a ferramenta correta para este trabalho. Você quer seguir este processo para garantir lembrar de mim os cookies em PHP :

Gerando um Lembrar token

  1. Gerar duas seqüências aleatórias:
    1. A selector que será utilizado para pesquisas de banco de dados. (A propósito de um seletor aleatório em vez de apenas uma identificação seqüencial é a não vazar quantos usuários ativos estão no seu site. Se você está confortável vazando essas informações, não hesite em usar apenas um ID seqüencial .)
    2. A validator que será usado para autenticar o usuário automaticamente.
  2. Calcular um hash de validator (a simples hash SHA-256 será suficiente).
  3. Guarde o selector e o hash do validator em uma tabela de banco de dados reservada para logins automáticos.
  4. Guarde o selector e validator em um cookie no cliente.

Resgatando um Lembrar token

  1. Split o cookie de entrada para o selector e validator.
  2. Realizar uma pesquisa de banco de dados (uso elaborou demonstrações !) Com base na selector.
  3. Se uma linha for encontrado, calcular um hash do validator.
  4. Compare o hash calculado no passo 3 com o hash armazenado no banco de dados, mais uma vez usando hash_equals() .
  5. Se a etapa 4 retorna verdade, efetuar login do usuário para a conta apropriada.

Esta é a estratégia que Gatekeeper adotado para a autenticação do usuário de longo prazo e é o mais seguro estratégia proposta até o momento para satisfazer este requisito.

Embora ambos uma forte queridos, AES é um padrão.

Quanto à segurança dos pequenos pedaços de dados: quanto menor - o melhor. Os dados menos criptografados é exposto, quanto mais tempo você pode usar a chave. Há sempre um limite teórico de quantos dados podem ser criptografados dentro de uma chave de determinado algoritmo sem expor sistema a riscos.

Se você criptografar o cookie, o servidor ainda tem para decodificá-la para lê-lo (para verificar a mesma chave), biscoito, portanto, qualquer criptografada é inútil, pois em caso de roubo (e un-editado) ainda levará o direito de hackers para sua conta. Sua tão inseguro como não criptografado em tudo.

Eu acredito que o verdadeiro problema de alguém roubar seu cookie é a conexão entre o servidor eo cliente. Usar conexão SSL fornecido pelo seu host.

Quanto ao seu cookie, você precisa fazer uma ID de longa aleatória por usuário no banco de dados, (tê-lo mudar a cada log on) e apenas definir isso como o cookie ou sessão. O cookie que contém a chave pode ser verificado através de php e se for igual a uma conta ou a tabela em seu banco de dados, despejar os dados na página web como normal.

Como apontado algumas vezes nos comentários anteriores, você deve se candidatar integridade protecção a qualquer texto cifrado que você envia para o usuário e aceitar de volta. Caso contrário, os dados protegidos pode ser modificada, ou a chave de encriptação recuperado.

Especialmente o mundo PHP está cheio de maus exemplos que ignoram isto (veja PHP criptografia - proceder com cuidado ) mas isso se aplica a qualquer linguagem.

Um dos poucos bons exemplos que eu vi é PHP-cryptlib que usa Criptografia combinado modo de autenticação para fazer o trabalho. Para Python pyOCB oferece funcionalidade similar.

Por que você quer para criptografar o cookie?

A meu ver, há dois casos:. Ou você dar ao cliente a chave, ou você não

Se você não dá a chave para o cliente, então por que você está dando-lhes a dados? A menos que você está jogando algum jogo estranho com a quebra de criptografia fraca (que você não está explicitamente), assim como você pode armazenar os dados no servidor.

Se você do mão o cliente a chave, então por que você criptografá-lo em primeiro lugar? Se você não criptografar a comunicação da chave, em seguida, criptografar o cookie é discutível: a MITM pode olhar para o cookie e enviar-lhe todo o bolinho que ele quer. Se você usar um canal criptografado para o cliente, porque a sobrecarga extra de criptografar os dados armazenados?

Se você está preocupado com outros usuários na máquina do cliente lê o cookie, desistir e assumir os conjuntos navegador boas bits de permissão:)

AES (também conhecido como Rijndael) é o mais popular. O tamanho do bloco é de 128 bits, que é apenas de 16 bytes, e você está falando "cerca de 100 caracteres".

Eu acho que "doar" quaisquer dados, mesmo criptografada quando se trata de nome de usuário e senha não é bom ... Há muitos JS que pode cheirar ... Sugiro que você crie em usuários de mesa DB uma cookie_auth campo ou qualquer outra coisa ...

após o primeiro login recolher: atual: navegador, IP, a ANS alguma chave próprio sal, além de seu hostname var ...

criar um hash e armazenar nesse campo ... definir um cookie ... Quando o Cookie "responde" comparar todos estes com o hash armazenado e feito ...

mesmo se alguém "roubar" um cookie não será capaz de usá-lo: -)

Espero que isso ajude: -)

FEHA vision.to

Além disso, eu tentei o mcrypt_encrypt e uma coisa por favor, mantenha em mente. Se você fizer base64_encode(mcrypt_encrypt(...)).

e, em seguida, mais tarde, você faz base64_decode e saída de dados criptografados (echo). Você provavelmente vai ser parafusado e não vendo nada. No entanto, se você fizer mcrypt_decrypt( ... base64_decode($value) ). Você vai ver os dados originais.

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