Criptografia em Rust: criptografia e hash com ring e sha2

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Criptografia em Rust: criptografia e hash com as bibliotecas ring e sha2



Rust é uma linguagem de programação de sistema que oferece segurança de memória e desempenho comparável a C/C++. Graças ao seu sistema de tipos rigoroso e modelo de propriedade, Rust é ideal para implementar algoritmos criptográficos, onde erros podem levar a vulnerabilidades graves. Neste artigo, veremos como usar as bibliotecas populares ring e sha2 para realizar operações criptográficas básicas: criptografia simétrica, hash e cálculo de HMAC.



Biblioteca ring: ferramenta universal para criptografia



A biblioteca ring é uma das bibliotecas criptográficas mais populares para Rust. Ela fornece implementações seguras de muitos algoritmos, incluindo AES-GCM para criptografia, SHA-256 para hash e HMAC para autenticação de mensagens. ring é escrita em Rust e C, garantindo alto desempenho e segurança.



Para começar, adicione a dependência ao seu Cargo.toml:



[dependencies]ring = "0.17"


Criptografia simétrica com AES-GCM



AES-GCM (Galois/Counter Mode) é um modo de criptografia que fornece tanto confidencialidade quanto autenticação de dados. É amplamente utilizado em protocolos modernos, como TLS.



Exemplo de criptografia e descriptografia de uma string usando ring:



use ring::aead::{Aad, LessSafeKey, Nonce, UnboundKey, AES_256_GCM};use ring::error::Unspecified;use ring::rand::{SecureRandom, SystemRandom};

fn encrypt(plaintext: &[u8], key: &[u8; 32]) -> Result<Vec<u8>, Unspecified> { let rng = SystemRandom::new(); let unbound_key = UnboundKey::new(&AES_256_GCM, key)?; let key = LessSafeKey::new(unbound_key);

// Geração de nonce aleatório (12 bytes) let mut nonce_bytes = [0u8; 12]; rng.fill(&mut nonce_bytes)?; let nonce = Nonce::assume_unique_for_key(nonce_bytes);

// Buffer para dados criptografados + tag de autenticação let mut in_out = plaintext.to_vec(); key.seal_in_place_append_tag(nonce, Aad::empty(), &mut in_out)?;

// Retorna nonce + dados criptografados let mut result = nonce_bytes.to_vec(); result.extend_from_slice(&in_out); Ok(result)}

fn decrypt(ciphertext: &[u8], key: &[u8; 32]) -> Result<Vec<u8>, Unspecified> { let unbound_key = UnboundKey::new(&AES_256_GCM, key)?; let key = LessSafeKey::new(unbound_key);

// Extrai nonce (primeiros 12 bytes) let (nonce_bytes, encrypted) = ciphertext.split_at(12); let nonce = Nonce::assume_unique_for_key(nonce_bytes.try_into().unwrap());

let mut in_out = encrypted.to_vec(); let plaintext = key.open_in_place(nonce, Aad::empty(), &mut in_out)?; Ok(plaintext.to_vec())}

fn main() { let key = b"01234567890123456789012345678901"; // 32 bytes para AES-256 let data = b"Mensagem secreta";

let encrypted = encrypt(data, key).unwrap(); println!("Criptografado: {:?}", encrypted);

let decrypted = decrypt(&encrypted, key).unwrap(); println!("Descriptografado: {}", String::from_utf8(decrypted).unwrap());}


Este código demonstra o ciclo completo de criptografia: geração de nonce aleatório, criptografia com tag de autenticação e descriptografia subsequente. Observe que o nonce deve ser único para cada criptografia com a mesma chave.



Hash com a biblioteca sha2



A biblioteca sha2 fornece implementações dos algoritmos da família SHA-2, incluindo SHA-256, SHA-384 e SHA-512. O hash é usado para verificar a integridade dos dados, armazenar senhas e criar assinaturas digitais.



Adicione a dependência:



[dependencies]sha2 = "0.10"


Exemplo de hash de uma string com SHA-256:



use sha2:                    

Recommendations