libsodium no PHP 7.2

Quem sou eu?

O que é criptografia?

é a prática e o estudo de técnicas para comunicação segura na presença de terceiros
é a construção e análise de protocolos que previnam terceiros de ler mensagens privadas

Tipos de criptografia

Simétrica

  • Utiliza uma mesma chave para criptografar e descriptografar os textos

Problema: Troca de chaves

Algoritmo Diffie–Hellman

Exemplificação do algoritmo Diffie-Hellman para troca de chaves

Fonte: Wikipedia

Assimétrica

  • Chave pública: utilizada para criptografar (escrever)
  • Chave privada: utilizada para descriptografar (ler)

Hashing

é uma função que mapeia dados de tamanho arbitrário para dados de tamanho fixo

Assinaturas

esquema matemático para demonstrar a autenticidade de uma mensagem

libsodium

Encrypt

// Lê a chave
$key = trim(file_get_contents('02-encrypt.key'));

// Gera um nonce
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);

// Prefixa o nonce aos dados para poder ser recuperado pelo decrypt
$ciphertext = sodium_bin2hex(
    $nonce . sodium_crypto_secretbox($plaintext, $nonce, $key)
);
// 7641ab3d68fedf4c52cc026aa1dcf611575a5843058483d281efa95b1577eddc6cb4ee37f5a8d8413e7ba6cd50

Decrypt

$ciphertext = sodium_hex2bin($ciphertext);

// Lê a chave
$key = trim(file_get_contents('02-encrypt.key'));

// Separa o nonce do texto
$nonce = substr($ciphertext, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$ciphertext = substr($ciphertext, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);

// Descriptografa
$plaintext = sodium_crypto_secretbox_open($ciphertext, $nonce, $key);

Assinatura

// Lê a chave
$key = trim(file_get_contents('03-auth.key'));

$auth = sodium_bin2hex(sodium_crypto_auth($ciphertext, $key));

Assinatura - Validando

$auth = sodium_hex2bin($auth);

// Lê a chave
$key = trim(file_get_contents('03-auth.key'));

// Verifica a assinatura
return sodium_crypto_auth_verify($auth, $ciphertext, $key);

Crypto Box

// Servidor 1 - Alice
$alice = sodium_crypto_box_keypair();
$alicePublic = sodium_crypto_box_publickey($alice);
$aliceSecret = sodium_crypto_box_secretkey($alice);

// Servidor 2 - Bob
$bob = sodium_crypto_box_keypair();
$bobPublic = sodium_crypto_box_publickey($bob);
$bobSecret = sodium_crypto_box_secretkey($bob);

Crypto Box - Alice

$nonce = random_bytes(SODIUM_CRYPTO_BOX_NONCEBYTES);

$key = sodium_crypto_box_keypair_from_secretkey_and_publickey(
    $aliceSecret, $bobPublic
);

$encrypted = sodium_crypto_box($message, $nonce, $key);
$ciphertext = $nonce . $encrypted;

Crypto Box - Bob

$nonce = substr($ciphertext, 0, SODIUM_CRYPTO_BOX_NONCEBYTES);
$ciphertext = substr($ciphertext, SODIUM_CRYPTO_BOX_NONCEBYTES);

$key = sodium_crypto_box_keypair_from_secretkey_and_publickey(
    $bobSecret, $alicePublic
);
echo sodium_crypto_box_open($encrypted, $nonce, $key);

Persistindo senhas

sodium_crypto_pwhash_str(
    $password,
    SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
    SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
);
// $argon2id$v=19$m=65536,t=2,p=1$20H8uU9EFq7GO2NFPrfDyg$Om/qimxzk9/7mub1s7bVEz/UbbIyikxBIrMlxZKPc/c

Validando senhas

sodium_crypto_pwhash_str_verify(
    $storedPassword,
    $inputPassword
);

Obrigado!