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: Também na biblioteca
StackExchange.Redis para C# (.NET): guia completo com exemplos práticos
Configuração de aplicações C# (.NET): bibliotecas e ferramentas
Guia completo do Twilio para JavaScript (Node.js) com exemplos
Configuração de aplicações em Go: melhores práticas e ferramentas