Criptografia de Dados de Aplicação em .NET: Das Bases ao Key Chain, Rotação e Compromissos de Busca

Criptografia de Dados de Aplicação em .NET: Das Bases ao Key Chain, Rotação e Compromissos de Busca

Explore as nuances da criptografia de dados sensíveis em aplicações .NET. Este artigo detalha desde os fundamentos até técnicas avançadas como key chains, rotação de chaves e os desafios da busca em dados criptografados, oferecendo soluções práticas e considerações de segurança.

MundiX News·18 de maio de 2026·19 min de leitura·👁 12 views

Se você já implementou um recurso que armazena dados pessoais – endereços de e-mail, notas em formato livre, tokens de API, números de identificação – certamente teve o mesmo pensamento incômodo: dificilmente se pode confiar em um banco de dados. Backups são copiados para laptops. Snapshots ficam em recursos de arquivos. A opção "encryption at rest" no console da nuvem protege apenas contra um tipo específico de roubo – o de alguém levar o disco.

Criptografar os dados antes que cheguem ao banco de dados parece simples no slide – AES, chave, pronto. No código real, a versão simples falha no momento em que você tenta rotacionar a chave, encontrar um registro por e-mail ou explicar ao revisor qual chave específica criptografou uma determinada string.

Neste artigo, analiso as opções de soluções para criptografar gradualmente propriedades individuais em .NET: famílias de algoritmos e por que os sistemas industriais os combinam, o que realmente protege o vetor de inicialização, por que você precisa de um keychain e não de uma única chave e um menu desagradável de opções para pesquisar dados criptografados. Usarei minha própria biblioteca EfCore.EncryptedProperties como um exemplo concreto de ponta a ponta. O principal aqui são os conceitos, a biblioteca é apenas uma forma de expressá-los.

1. O Que Realmente Queremos Dizer com “Criptografia de Documentos”

Este termo cobre várias coisas diferentes. Para definir honestamente os limites, aqui está sobre o que este artigo trata e sobre o que não trata:

Dentro do escopo:

  • Criptografia de valores individuais – colunas, propriedades, campos JSON – antes que cheguem ao banco de dados. A chave é armazenada pelo aplicativo (diretamente ou por meio de um KMS), e o banco de dados vê apenas o texto cifrado.

Fora do escopo:

  • Criptografia de disco completo (BitLocker, LUKS, Storage Service Encryption). TLS, que protege os bytes em trânsito, não em repouso. Criptografia de mensagens de ponta a ponta, onde o próprio servidor de aplicativos não tem acesso ao texto não criptografado. MSSQL “Always encrypted” com chaves no banco de dados.

O modelo de ameaças é o mais comum. Imagine que o pior aconteceu com seu banco de dados – um backup roubado, um snapshot copiado – e o invasor tem cada linha que você já escreveu. Idealmente, ele vê blobs opacos, inúteis sem a chave gerenciada pelo seu aplicativo.

O que essa criptografia não protege é igualmente importante. Se um invasor comprometer o processo do aplicativo, ele poderá descriptografar tudo o que o processo puder descriptografar – ponto final. Uma injeção SQL que retorna uma string retornará exatamente o que o aplicativo descriptografaria em uma solicitação normal. Um dump de memória capturará o texto não criptografado imediatamente após a descriptografia. Propriedades criptografadas são uma cerca ao redor do armazenamento de dados, não ao redor do aplicativo.

Em geral, nosso roteiro é o seguinte: famílias de algoritmos > modos e IV > criptografia de envelope > keychains > rotação > localização das chaves > pesquisa em dados criptografados > exemplo elaborado.

2. Duas Famílias de Algoritmos – E Por Que Ambas São Necessárias

A criptografia de confidencialidade é claramente dividida em duas famílias.

Criptografia simétrica usa uma única chave secreta para criptografia e descriptografia. AES é o representante dominante. É rápido – os processadores modernos têm instruções AES dedicadas e podem criptografar gigabytes por segundo em um único núcleo – e funciona com dados de comprimento arbitrário. A desvantagem é operacional: todos que precisam criptografar ou descriptografar precisam da chave, então entregar a chave a essas partes de forma segura é o seu problema.

Criptografia assimétrica usa um par de chaves: a chave pública criptografa, a chave privada descriptografa. RSA é um exemplo de livro didático. A distribuição de chaves é resolvida por construção – a chave pública pode ser publicada em qualquer lugar – mas duas propriedades inconvenientes tornam a criptografia assimétrica uma má escolha para “criptografar um documento”:

  • É lento. Duas a três ordens de magnitude mais lento que AES para a mesma quantidade de dados.
  • O tamanho do texto não criptografado é limitado pelo tamanho da chave. RSA-OAEP com uma chave de 2048 bits atinge cerca de 190 bytes por operação. Útil para uma chave, inútil para um registro.

A resposta industrial padrão é usar ambos, em um esquema chamado criptografia de envelope: um algoritmo simétrico faz o trabalho principal, e um assimétrico (ou KMS) protege a chave simétrica. A seção 4 analisa isso em detalhes. O ponto principal é que “AES vs RSA” é uma falsa escolha: você quase sempre precisa de um payload criptografado com AES e uma chave encapsulada com RSA, em um envelope estável que pode ser salvo e analisado.

EfCore.EncryptedProperties usa AES-256-GCM para o payload e RSA-OAEP-SHA-256 para encapsular as chaves simétricas. Ambas as famílias estão no lugar, e cada uma faz o que faz de melhor.

3. AES – Modo e IV Não São Detalhes de Implementação

Dizer “criptografamos com AES” não diz quase nada. AES é uma cifra de bloco, por si só transforma 16 bytes de texto não criptografado em 16 bytes de texto cifrado. Todo o resto – como criptografar 17 bytes, como processar os próximos 16, se dois textos não criptografados idênticos dão o mesmo texto cifrado – é resolvido pelo modo. A segurança reside precisamente no modo.

Visão geral prática:

  • ECB (Electronic Codebook). Cada bloco de 16 bytes é criptografado independentemente. Blocos idênticos de texto não criptografado dão blocos idênticos de texto cifrado – é por isso que a famosa imagem do “pinguim criptografado com ECB” ainda é reconhecível. Não use ECB.
  • CBC (Cipher Block Chaining). Cada bloco é XORed com o bloco de texto cifrado anterior antes da criptografia, a etapa inicial é definida pelo vetor de inicialização (IV). Evita o vazamento do ECB, mas não garante a integridade – um bit invertido do texto cifrado se torna um bit invertido do texto não criptografado mais adiante na cadeia. Precisa de um MAC separado, e as pessoas constantemente fazem sua construção incorretamente.
  • CTR (Counter). Transforma uma cifra de bloco em uma cifra de fluxo, criptografando valores de contador sequenciais e XORing-os com o texto não criptografado. Rápido, mas novamente sem integridade.
  • GCM (Galois/Counter Mode). Modo CTR mais uma tag de autenticação calculada durante a criptografia. O destinatário verifica a tag antes de retornar o texto não criptografado, a falsificação é detectada. Isso é o que você precisa.

GCM aceita três entradas além da chave e do texto não criptografado:

  • IV (canonicamente 12 bytes),
  • dados associados (AAD – autenticáveis, mas não criptografados, úteis para vincular o texto cifrado ao contexto) e emite uma
  • tag de autenticação de 16 bytes ao lado do texto cifrado.

A regra mais importante sobre IV em GCM:

nunca reutilize o IV com a mesma chave.

Não “será mais fraco”, mas catastroficamente quebrado. Duas mensagens criptografadas com o mesmo par (chave, IV) vazam o XOR de seus textos não criptografados, e a chave de autenticação pode ser recuperada, permitindo que um invasor falsifique mensagens como quiser. Essa regra enterrou não poucos sistemas industriais.

Existem três maneiras razoáveis de evitar que isso aconteça:

  • Aleatório em cada criptografia. Gere um novo IV de 96 bits com um CSPRNG a cada vez. Com 2⁹⁶ valores possíveis, as colisões são extremamente improváveis até que você criptografe cerca de 2⁴⁸ mensagens com uma única chave.
  • Contador determinístico. Mantenha um contador monotônico na área de uma única chave. Funciona bem se você puder garantir que as partes criptografadoras paralelas não o perderão, em um serviço escalável horizontalmente é mais complicado do que parece.
  • Sintético / SIV. Derive o IV deterministicamente da chave + AAD + texto não criptografado (AES-SIV, AES-GCM-SIV). Troca um pouco de desempenho por resistência ao uso indevido do IV.

EfCore.EncryptedProperties usa a opção 1 – a solução padrão padrão:

csharp
// src/EfCore.EncryptedProperties/Cryptography/AesGcmEncryptor.cs
private const int IvSizeBytes = 12;
private const int TagSizeBytes = 16;

public static (byte[] Ciphertext, byte[] Tag, byte[] Iv) Encrypt(byte[] key, byte[] plaintext, byte[] aad)
{
    var iv = RandomNumberGenerator.GetBytes(IvSizeBytes);
    var ciphertext = new byte[plaintext.Length];
    var tag = new byte[TagSizeBytes];

    using var aesGcm = new AesGcm(key, TagSizeBytes);
    aesGcm.Encrypt(iv, plaintext, ciphertext, tag, aad);
    return (ciphertext, tag, iv);
}

Três detalhes de implementação que valem a pena apontar: IV de 12 bytes – o tamanho padrão para GCM (mais rápido que 16 bytes, não precisa de uma etapa de hashing), tag de 16 bytes – o máximo e a única escolha razoável se houver espaço, using em AesGcm é importante porque o tipo mantém um handle de chave não gerenciado.

Um efeito colateral de IVs aleatórios em cada criptografia é que o texto cifrado não é determinístico. Criptografe a string alice@example.com duas vezes com a mesma chave – obtenha dois blobs diferentes. É precisamente essa propriedade que impede que o banco de dados responda a WHERE Email = 'alice@example.com' – e analisaremos isso na seção 8.

4. Envelope Encryption – CEK, KEK e Chave Mestra

Até agora, tínhamos uma chave AES, opaca e supostamente mágica. A solução ingênua é colocá-la em appsettings.json e considerar o trabalho feito. Dois requisitos quebram rapidamente esse design: rotação (a chave deve mudar sem tempo de inatividade para recriptografar) e armazenamento da chave (a chave deve estar em algum lugar mais difícil de alcançar do que a configuração do aplicativo).

A resposta é criptografar os dados com uma chave de curta duração e armazenar essa chave de curta duração ao lado do texto cifrado, enquanto a criptografa com uma chave de longa duração. Essa aninhamento é Envelope encryption, e a versão industrial usa três níveis:

  • CEK – Content Encryption Key (chave de criptografia de conteúdo). Uma nova chave AES, gerada para cada valor criptografado. Ela criptografa o texto não criptografado real e é imediatamente encapsulada. CEK é descartável.
  • KEK – Key Encryption Key (chave de criptografia de chave). Uma chave AES de vida útil mais longa, encapsulando a CEK. Geralmente uma por propósito (mais sobre isso na seção 5). Rotacionada de acordo com o calendário.
  • Chave mestra. Raiz de confiança. Vive em um armazenamento reforçado – KMS, HSM, Azure Key Vault, em um arquivo pfx/pem criptografado. Encapsula a KEK. Rotacionada raramente.

Por que três níveis? Porque cada um tem seu próprio perfil de custo. As CEKs não são particularmente valiosas, pois criptografam apenas um documento, são baratas de gerar. As chaves KEK são um pouco mais valiosas, são rotacionadas de acordo com a programação, devem viver tempo suficiente para descriptografar tudo o que já criptografaram. As chaves mestras são caras de substituir (elas podem viver em HSMs com logs de auditoria e controle de acesso físico), as chamadas para elas podem ser caras, então você quer ter o mínimo possível de operações sobre elas. A estrutura “wrapper-in-wrapper” permite que cada nível faça seu trabalho.

O formato de fio de fato para um blob criptografado em envelope é JWE (JSON Web Encryption) compact serialization, empacotando tudo em cinco segmentos, separados por um ponto e codificados em base64url:

{header}.{wrapped CEK}.{IV}.{ciphertext}.{auth tag}

EfCore.EncryptedProperties serializa exatamente isso:

csharp
// src/EfCore.EncryptedProperties/Cryptography/JweCompactSerializer.cs
public static string Serialize(JweHeader header, byte[] wrappedCek, byte[] iv, byte[] ciphertext, byte[] tag)
{
    var headerB64 = Base64Url.Encode(Encoding.UTF8.GetBytes(header.ToJson()));
    var encKeyB64 = Base64Url.Encode(wrappedCek);
    var ivB64 = Base64Url.Encode(iv);
    var ciphertextB64 = Base64Url.Encode(ciphertext);
    var tagB64 = Base64Url.Encode(tag);
    return $"{headerB64}.{encKeyB64}.{ivB64}.{ciphertextB64}.{tagB64}";
}

O cabeçalho é um pequeno objeto JSON. Ele carrega identificadores de algoritmo e – criticamente – kid (key id), que indica qual KEK encapsulou esta CEK:

json
{
  "alg": "A256GCMKW",
  "enc": "A256GCM",
  "kid": "8f4c1b2e-3a9d-4c2e-9b1a-7c5e3a1d2f4b",
  "iv":  "...",
  "tag": "..."
}

alg descreve o algoritmo de encapsulamento de chave (AES-GCM key wrap com uma chave de 256 bits).

enc descreve o algoritmo de conteúdo (AES-256-GCM).

iv e tag dentro do cabeçalho protegem a própria operação de encapsulamento, iv e tag fora (segmentos 3 e 5) protegem o payload. Duas operações AES-GCM, dois IVs e tags independentes.

Hierarquia de envelope:

┌───────────────────────────┐
│  Chave Mestra (RSA / HSM)  │
└──────────────┬────────────┘
               │ encapsula
               ▼
┌───────────────────────────┐
│   KEK (AES por propósito)   │
└──────────────┬────────────┘
               │ encapsula
               ▼
┌───────────────────────────┐
│   CEK (AES por valor)     │
└──────────────┬────────────┘
               │ criptografa
               ▼
         Texto não criptografado

Por que isso é importante para o banco de dados: cada valor criptografado carrega o kid de sua KEK em seu próprio envelope. O aplicativo nunca precisa adivinhar qual chave descriptografar – o texto cifrado diz a ele. É precisamente essa propriedade que torna possível a próxima seção.

5. Keychains – Quando Há Mais de Uma Chave

É hora de olhar para o design ingênuo de “uma chave na configuração” na vida real.

Cenário: a equipe de segurança pede que você rotacione a chave de criptografia a cada 90 dias. Com uma chave na configuração, você tem duas opções:

  1. Parar o mundo, recriptografar cada linha, lançar uma nova chave. Real para uma tabela de 10.000 linhas. Catastrófico para uma tabela de 100 milhões de linhas.
  2. Desistir da rotação. Dizer à equipe de segurança que o armazenamento de dados não pode atender à sua política.
  3. Armazenar uma coleção de chaves, tentar descriptografar todas em ordem =)

Nem um, nem outro, e certamente não o terceiro. Além disso, não há como o texto cifrado responder à pergunta “qual chave criptografou esta linha”, então mesmo entender o que precisa ser recriptografado se torna uma adivinhação. E se seu aplicativo armazena e-mails de clientes e notas médicas em formato livre com a mesma chave, comprometer essa chave compromete ambos – não há história sobre o raio de explosão.

Um keychain resolve todos os três problemas. É uma coleção de chaves versionada, dividida por propósito, com uma atualmente ativa para novas gravações e todas as antigas mantidas para leituras:

  • As gravações sempre usam a chave atualmente ativa para o propósito correspondente.
  • As leituras olham para o kid no envelope do texto cifrado e obtêm precisamente essa chave do keychain, independentemente de estar ativa ou não.
  • Os propósitos dividem as chaves por classe de dados: email, notes, tokens, cada um potencialmente com sua própria programação de rotação e raio de explosão independentes.

Especificamente, aqui está como a biblioteca modela um registro KEK:

csharp
// src/EfCore.EncryptedProperties/KeyManagement/EncryptedKeyRecord.cs
public sealed class EncryptedKeyRecord
{
    public required Guid Id { get; init; }
    public required string Purpose { get; init; }
    public required string RsaKeyId { get; init; }
    public required string Algorithm { get; init; }
    public required string EncryptedKey { get; init; }
    public required DateTimeOffset CreatedAt { get; init; }
    public required bool IsActive { get; init; }
}

Vários detalhes que valem a pena notar.

  • Id é o que entra em cada envelope de texto cifrado como kid.
  • Purpose é o domínio de dados.
  • RsaKeyId registra qual versão da chave mestra encapsulou esta KEK – importante se você alguma vez rotacionar a chave mestra, porque as KEKs antigas ainda apontam para a versão do mestre que as encapsulou.
  • EncryptedKey é a própria KEK, já encapsulada pela chave mestra, então é seguro fazer backup da linha do banco de dados.

O gerenciador de keychain toma a decisão de “qual chave usar”:

csharp
// src/EfCore.EncryptedProperties/KeyManagement/KeyChainManager.cs
public async ValueTask<KeyMaterial> GetActiveKeyAsync(string purpose, CancellationToken cancellationToken = default)
{
    // ...verificação de cache, bloqueios omitidos...
    var record = await _storage.GetActiveAsync(purpose, cancellationToken);
    var shouldRotate = record is not null && ShouldRotate(record);

    if (record is not null && !shouldRotate)
    {
        var decrypted = await DecryptKekAsync(record, cancellationToken);
        // cache + retorno
        return decrypted;
    }
    // ...gerar nova KEK, salvar, registrar evento, retornar...
}

private bool ShouldRotate(EncryptedKeyRecord record)
{
    if (_options.RotationPolicy.KeyRotateAfter is not { } maxAge)
        return false;

    return DateTimeOffset.UtcNow - record.CreatedAt > maxAge;
}

Duas coisas que valem a pena notar. Primeiro, GetActiveKeyAsync é a única operação que alguma vez cria uma nova KEK – e faz isso apenas quando não há registro ativo ou o registro existente passou da idade de rotação. Segundo, GetKeyForDecryptAsync(keyId) existe separadamente para o caminho de leitura, que procura por kid do envelope, não por propósito. As leituras nunca acionam a rotação. As gravações sim.

Conectar propósitos ao modelo de entidade é uma linha por propriedade. A biblioteca suporta tanto atributo quanto API fluente:

csharp
public sealed class Customer
{
    public Guid Id { get; set; }

    [Encrypted("email")]
    public string Email { get; set; } = string.Empty;

    [Encrypted(KeyPurpose = "notes")]
    public EncryptedValue<string> SecretNotes { get; set; } = default!;
}

Email e SecretNotes agora vivem em keychains independentes. Rotacionar email não faz nada com notes e vice-versa. Comprometer uma KEK na área de notes não revela nenhum email. É essa propriedade de segregação que um design de raiz única não pode dar.

Último ponto: o keychain padrão mantém as KEKs antigas. Elas não são excluídas, apenas param de estar ativas para gravações – em algum lugar sempre há outra linha criptografada sob a chave antiga, até que você prove o contrário.

6. Rotação – Preguiçosa É Melhor Que Gananciosa

Existem duas estratégias para “rotacionar uma chave”. Muitas equipes imaginam a errada.

Rotação gananciosa é a estratégia que a maioria das pessoas desenha no quadro branco: quando uma nova chave chega, recriptografar cada linha existente, então retirar a antiga de circulação. Funciona para uma tabela de 10.000 linhas. Em uma tabela de 100 milhões de linhas, é uma interrupção, e em um banco de dados multi-inquilino, é uma migração de vários dias com procedimentos de reversão e muitas reuniões.

Rotação preguiçosa é a estratégia que realmente escala. Quando uma nova chave chega:

  • Novas gravações usam a nova chave.
  • As linhas existentes permanecem exatamente como estão – criptografadas com a chave antiga – e a chave antiga é mantida no keychain.
  • As leituras pegam o kid do envelope de cada linha e descriptografam com a chave que a encapsulou.

Com 100 milhões de linhas existentes, nada acontece. Sem interrupção, sem migração, sem plano de reversão. O preço é que a chave antiga deve permanecer, o que é essencialmente gratuito.

A biblioteca inclui rotação com uma única chamada fluente. A própria verificação é o método ShouldRotate, mostrado acima:

csharp
services.AddEncryptedProperties(cfg => cfg
    .WithFileRsaKeyProvider("rsa-key.pem", "rsa-v1")
    .WithDatabaseKeyChain(SqlClientFactory.Instance, connectionString)
    .WithKeyChainRotation(policy =>
    {
        policy.KeyRotateAfter = TimeSpan.FromDays(90);
    }));

Após 90 dias, a próxima gravação para um determinado propósito aciona a geração de KEK, a KEK antiga se torna IsActive = false e permanece na tabela, e a vida continua.

Quando realmente precisa recriptografar gananciosamente? Apenas quando há uma razão pela qual uma determinada chave antiga não pode continuar existindo: suspeita plausível de comprometimento, um regulador exigindo “nenhum dado com mais de X, criptografado com a chave Y”. Então você executa uma tarefa em segundo plano que lê cada linha afetada, descriptografa com a KEK antiga, regrava (o que criptografa com a nova KEK) e, assim que o contador chegar a zero, você pode excluir o registro antigo. É factível, apenas não é o caminho de rotação padrão.

A segunda metade da rotação – auditabilidade – é a parte que se transforma em uma questão de conformidade. Os revisores querem saber: quando a chave mudou? Quem acionou? As descriptografias falharam na janela depois? A biblioteca gera exatamente quatro IDs de evento para essa conversa:

csharp
// src/EfCore.EncryptedProperties/EncryptedPropertiesEventIds.cs
public static readonly EventId KeyCreated         = new(1000, nameof(KeyCreated));
public static readonly EventId KeyRotated         = new(1001, nameof(KeyRotated));
public static readonly EventId KeyPreloadFailed   = new(1002, nameof(KeyPreloadFailed));
public static readonly EventId DecryptionFailed   = new(1003, nameof(DecryptionFailed));

A string de log KeyRotated carrega cada campo que o revisor solicitará – id da chave antiga, id da nova chave, qual versão da chave mestra encapsulou cada uma delas, ambos os carimbos de data/hora de criação:

csharp
_logger.LogInformation(
    EncryptedPropertiesEventIds.KeyRotated,
    "Rotated encrypted property KEK for purpose {Purpose} from key {OldKeyId} to key {NewKeyId}. " +
    "Old RSA key {OldRsaKeyId}, new RSA key {NewRsaKeyId}. " +
    "Old created at {OldCreatedAt}; new created at {NewCreatedAt}.",
    ...);

Envie eventos de rotação para o log de auditoria por padrão – o revisor perguntará.

7. Onde Vive a Chave Mestra?

Três formas de implantação em ordem crescente de maturidade operacional:

  • Na memória. O provedor mantém uma instância RSA, existente durante a vida útil do processo e desaparecendo com seu término. Útil para testes, demos locais e fixações de teste de integração, onde você não quer gerenciar o estado no disco. Não para algo que você pretende ler amanhã.
csharp
services.AddEncryptedProperties(cfg => cfg
    .WithInMemoryRsaKeyProvider(RSA.Create(2048), "test-rsa-v1")
    .WithInMemoryKeyChain());
  • Arquivo no disco (PEM). O provedor aponta para um arquivo PEM. Se o arquivo estiver ausente na inicialização, ele gera uma nova chave RSA e a grava. Esta é a forma “auto-hospedada, uma máquina”, e para ela funciona bem – pequenos serviços, instalações on-prem, projetos de hobby, onde a superfície operacional deve permanecer pequena:
csharp
// src/EfCore.EncryptedProperties/Providers/FileRsaKeyProvider.cs
public FileRsaKeyProvider(string filePath, string keyId, int keySizeInBits = 2048)
{
    KeyId = keyId;

    if (File.Exists(filePath))
    {
        _rsa = RSA.Create();
        _rsa.ImportFromPem(File.ReadAllText(filePath));
    }
    else
    {
        _rsa = RSA.Create(keySizeInBits);
        var dir = Path.GetDirectoryName(filePath);
        if (!string.IsNullOrEmpty(dir))
            Directory.CreateDirectory(dir);
        File.WriteAllText(filePath, _rsa.ExportRSAPrivateKeyPem());
    }
}

O compromisso é honesto: o arquivo PEM agora é algo que sua estratégia de backups deve levar em conta. Perder o PEM – e cada coluna criptografada é irrecuperável. Trate o arquivo como qualquer outro segredo do aplicativo – permissões no sistema de arquivos, não sob controle de versão, incluído nos procedimentos de DR.

O Crypto API Store da máquina é uma boa opção, especialmente se seu host fizer parte de um domínio onde há gerenciamento centralizado de certificados.

  • KMS – Azure Key Vault. O provedor mantém um KeyClient, direcionado a uma chave no Key Vault. O processo local nunca vê a chave RSA privada. Para encapsular uma nova KEK, o processo local obtém a chave pública (armazenada em cache) e criptografa. Para desdobrar uma KEK existente, o processo local envia os bytes encapsulados para o Key Vault e recebe de volta a CEK desdobrada:
csharp
// src/EfCore.EncryptedProperties/Providers/AzureKeyVaultRsaKeyProvider.cs
public async ValueTask<byte[]> UnwrapKeyAsync(
    byte[] ciphertext,
    string rsaKeyId,
    CancellationToken cancellationToken = default)
{
    // ...
    var cryptoClient = _cryptoClients.GetOrAdd(
        rsaKeyId,
        keyId => new CryptographyClient(new Uri(keyId), _credential));

    var result = await cryptoClient.UnwrapKeyAsync(
        KeyWrapAlgorithm.RsaOaep256,
        ciphertext,
        cancellationToken);
    return result.Key;
}

Duas consequências. Primeiro, UnwrapKeyAsync é uma chamada de rede, então o gerenciador de keychain armazena agressivamente em cache as KEKs desdobradas na memória. Segundo, a história operacional é dramaticamente melhor: RBAC na chave, logs de auditoria de cada wrap/unwrap, soft-delete e purge protection, e uma chave privada que nunca é extraível do vault.

Nos três casos, o mesmo envelope acaba no disco. Mas a diferença de “laptop roubado” entre a implantação de arquivo e o Key Vault é enorme – no primeiro caso, o invasor tem o PEM e pode descriptografar como quiser, no segundo, ele tem blobs opacos e não tem como alcançar o vault.

8. A Tarefa de Pesquisa – E Um Menu de Respostas Ruins

Esta é a seção que os diagramas de arquitetura geralmente omitem. Se você criptografar uma coluna corretamente – nova CEK por gravação, IV aleatório, texto cifrado AES-GCM – então o mesmo texto não criptografado sempre dá um texto cifrado diferente. É precisamente essa propriedade de segurança que você precisa. É precisamente ela que torna impossível para o banco de dados responder a:

sql
-- Isso não vai funcionar :(
var customer = await db.Customers
    .SingleOrDefaultAsync(c => c.Email == "alice@example.com");

WHERE compara dois blobs de texto cifrado que nunca corresponderão – embora os textos não criptografados correspondam. Índices em colunas criptografadas são inúteis para pesquisa por igualdade. JOIN é inútil.

LIKE é desesperador.

ORDER BY retorna linhas ordenadas por texto cifrado aleatório.

Existem cinco respostas, todas com compromissos. Eu vou nomear o que cada um e o que paga – não há opção gratuita aqui.

Opção A – Criptografia Determinística.

Remover a aleatoriedade: criptografar

🛡️⚡

Pare de pesquisar. Comece a hackear.

O MundiX é seu copiloto de pentest com IA: comandos exatos, análise de outputs e próximo passo na kill chain — em segundos.

Testar grátis por 7 dias →

Sem cartão para começar · Planos a partir de R$49/mês

📤 Compartilhar & Baixar

🧰 Ferramentas recomendadas

Divulgação: alguns links são patrocinados. Podemos receber comissão se você comprar — sem custo extra para você. Só indicamos o que faz sentido para a comunidade.

Aprendendo Kali Linux: Teste de segurança, pentest e hacking ético

Aprendendo Kali Linux: Teste de segurança, pentest e hacking ético

Com centenas de ferramentas pré-instaladas, a distribuição Kali Linux facilita o trabalho de os profissionais de segurança começarem a fazer testes de segurança rapidamente. No entanto, com mais de 600 ferramentas em seu arsenal, o Kali Linux também pode ser desafiador. A nova edição deste prático livro abrange as atualizações nas ferramentas e inclui uma melhor abordagem da análise forense e da engenharia reversa. Ric Messier, autor, não fica apenas no teste de segurança, mas também faz uma abordagem sobre a execução de análise forense, incluindo a análise em disco e na memória, assim como alguma análise básica de malware. • Explore as diversas ferramentas disponíveis no Kali Linux • Entenda o valor do teste de segurança e examine os tipos de teste disponíveis • Aprenda os aspectos básicos do pentest em todo o ciclo de vida do ataque • Instale o Kali Linux em vários sistemas, tanto físicos quanto virtuais • Descubra como usar diferentes ferramentas destinadas à segurança • Estruture um teste de segurança baseado nas ferramentas do Kali Linux • Estenda as ferramentas do Kali para criar técnicas de ataque avançadas • Use o Kali Linux para ajudar a criar relatórios quando o teste terminar “A abordagem concisa, clara e baseada na experiência adotada por Ric Messier para a introdução do Kali Linux e dos testes de cibersegurança é incomparável. Este livro é uma leitura excelente e acessível para iniciantes e um recurso valioso para qualquer pessoa.” —Alexander Arlt, Consultor sênior de segurança, Google

Ver na Amazon
Gshield 2 em 1 Hub Extensor Conector USB-C + USB-A e Adaptador de Rede Ethernet LAN RJ45 com 3 Entradas USB 3.0 até 5 Gbps em Liga de Alumínio para Computador e Notebook, Cinza

Gshield 2 em 1 Hub Extensor Conector USB-C + USB-A e Adaptador de Rede Ethernet LAN RJ45 com 3 Entradas USB 3.0 até 5 Gbps em Liga de Alumínio para Computador e Notebook, Cinza

Compatível com portas USB-C e USB-A, ideal para ampliar a conectividade de dispositivos como MacBook Pro e outros com portas USB-C. Inclui um adaptador USB-A extra, proporcionando uma conexão Ethernet estável e veloz de até 1 Gbps, perfeita para filmes, jogos online e videoconferências. Oferece três portas USB 3.0 com velocidades de transferência de até 5 Gbps, permitindo conectar mouse, teclado, discos rígidos e outros periféricos. Fabricado em alumínio durável, garantindo longa vida útil e resistência ao uso diário. Design compacto e leve, ideal para viagens de negócios e uso diário, facilitando o transporte e armazenamento. Funciona com Windows 10/8.1/8, Mac OS e Chrome OS, oferecendo versatilidade incomparável para diversas necessidades de conectividade. Assegura uma conectividade estável e rápida, perfeita para tarefas exigentes como transferência de dados, streaming e mais.

Ver na Amazon
Hacking APIs: Breaking Web Application Programming Interfaces

Hacking APIs: Breaking Web Application Programming Interfaces

Hacking APIs is a crash course on web API security testing that will prepare you to penetration-test APIs, reap high rewards on bug bounty programs, and make your own APIs more secure. You'll learn how REST and GraphQL APIs work in the wild and set up a streamlined API testing lab with Burp Suite and Postman. Then you'll master tools useful for reconnaissance, endpoint analysis, and fuzzing, such as Kiterunner and OWASP Amass. Next, you'll learn to perform common attacks, like those targeting an API's authentication mechanisms and the injection vulnerabilities commonly found in web applications. You'll also learn techniques for bypassing protections against these attacks. In the book's nine guided labs, which target intentionally vulnerable APIs, you'll practice: Enumerating APIs users and endpoints using fuzzing techniques Using Postman to discover an excessive data exposure vulnerability Performing a JSON Web Token attack against an API authentication process Combining multiple API attack techniques to perform a NoSQL injection Attacking a GraphQL API to uncover a broken object level authorization vulnerability

Ver oferta
Gray Hat Hacking: The Ethical Hacker's Handbook, Sixth Edition

Gray Hat Hacking: The Ethical Hacker's Handbook, Sixth Edition

Up-to-date strategies for thwarting the latest, most insidious network attacks This fully updated, industry-standard security resource shows, step by step, how to fortify computer networks by learning and applying effective ethical hacking techniques. Based on curricula developed by the authors at major security conferences and colleges, the book features actionable planning and analysis methods as well as practical steps for identifying and combating both targeted and opportunistic attacks. Gray Hat Hacking: The Ethical Hacker's Handbook, Sixth Edition clearly explains the enemy's devious weapons, skills, and tactics and offers field-tested remedies, case studies, and testing labs. You will get complete coverage of Internet of Things, mobile, and Cloud security along with penetration testing, malware analysis, and reverse engineering techniques. State-of-the-art malware, ransomware, and system exploits are thoroughly explained. Fully revised content includes 7 new chapters covering the latest threats Includes proof-of-concept code stored on the GitHub repository Authors train attendees at major security conferences, including RSA, Black Hat, Defcon, and B-Sides

Ver na Amazon
Bloqueador USB de privacidade de porta USB para PC, notebook, bloco de laptop,

Bloqueador USB de privacidade de porta USB para PC, notebook, bloco de laptop,

Proteção de privacidade aprimorada: protege o link de transmissão de dados para evitar roubo de informações, fornecendo proteção de segurança robusta que protege a privacidade do usuário durante transferências de arquivos e garante uma conexão segura para interações de dispositivos sem preocupações em vários ambientes Uso a longo prazo: a camada protetora resistente ao desgaste, combinada com um corpo de metal resistente, oferece gerenciamento de calor confiável e qualidade duradoura durante o uso diário Entrega eficiente de energia: a tecnologia de chip inteligente garante a identificação automática dos requisitos de energia, fornecendo carregamento eficiente alinhando-se com vários protocolos de carregamento rápido para maior conveniência Proteção contra sobrecarga: evitando riscos de sobrecarga, este bloqueador de dados USB protege a vida útil da bateria e garante um desempenho estável, mantendo um fluxo estável de energia para melhorar a longevidade do dispositivo de forma eficaz Prático de transportar: com atenção à portabilidade, este bloqueador de dados USB oferece um design compacto que é leve e fácil de transportar, melhorando a conveniência do usuário e operação eficiente

Ver na Amazon

📩 Newsletter MundiX

Receba novidades de cibersegurança + um checklist de pentest grátis. Sem spam.

Ao assinar você concorda em receber e-mails. Cancele quando quiser.