C# - Usando a classe ProtectedData

 Neste artigo veremos como usar os recursos da classe ProtectedData do .NET Framework.

O .NET Framework fornece acesso à API de proteção de dados (DPAPI), que permite criptografar dados usando informações da conta de usuário atual ou do computador.

Quando você usa o DPAPI, você alivia o difícil problema de gerar e armazenar explicitamente uma chave criptográfica.

Isso é possível graças aos recursos disponíveis na classe ProtectedData do namespace System.Security.Cryptography.

Esta classe fornece acesso à API de proteção de dados (DPAPI) disponível no Microsoft Windows 2000 e sistemas operacionais posteriores. Este é um serviço que é fornecido pelo sistema operacional e não requer bibliotecas adicionais. Ele fornece proteção usando as credenciais do usuário ou da máquina para criptografar ou descriptografar dados.

A classe consiste em dois métodos estáticos, Protect e Unprotect não gerenciados. Esses dois métodos podem ser usados para criptografar e descriptografar dados, como senhas, chaves e cadeias de conexão.

Você pode especificar que os dados criptografados pela conta de usuário atual possam ser descriptografados somente pela mesma conta de usuário ou por qualquer conta no computador.

O escopo da proteção dos dados pode ser definido pela enumeração DataProtectionEscope que apresenta os valores:

Mas atenção!!!, a enumeração LocalMachine permite que várias contas possam desproteger dados. Use esse valor somente quando confiar em todas as contas de um computador. Para a maioria das situações, você deve usar o valor CurrentUser.

Além disso, a enumeração MemoryProtectionScope define o escopo da proteção da memória pelo método Protect, e, possui os seguintes valores:

 CrossProcess         1    Todo o código em qualquer processo pode desproteger a memória que
foi protegida usando o método Protect.
 SameLogon 2 Apenas o código em execução no mesmo contexto de usuário que o
código que chamou o método Protect, pode desproteger a memória.
 SameProcess 0 Apenas o código em execução no mesmo processo que o código que
chamou o método Protect, pode desproteger a memória.

Vejamos a seguir um exemplo prático.

Usando a classe ProtectedData

Vamos criar um projeto Console App (.NET Framework) usando o Visual Studio 2019 Community chamado CShp_ProtectedData1

A seguir inclua uma referência ao assembly System.Security no projeto :

A seguir defina o código abaixo no arquivo Program.cs :

using System;
using System.Security.Cryptography;
using static System.Console;
namespace CShp_ProtectedData1
{
    class Program
    {
        // Cria um array para incluir maior complexidade (maior entropia) ao usar o método Protect
        static byte[] _entropiaAdicional = { 9, 8, 7, 6, 5 };
        static void Main(string[] args)
        {
            // Cria um array de bytes contendo os dados a serem criptografados
            byte[] segredo = { 0, 1, 2, 3, 4, 1, 2, 3, 4 };
            //Criptografa os dados
            byte[] segredoCifrado = Protege(segredo);
            WriteLine("O array de bytes cifrado é : ");
            ImprimeValores(segredoCifrado);
            // Decifra os dados e armazena no array de bytes
            byte[] dadosOriginais = Desprotege(segredoCifrado);
            WriteLine("Os dados originais são : ", Environment.NewLine);
            ImprimeValores(dadosOriginais);
        }
        public static byte[] Protege(byte[] dados)
        {
            try
            {
                // Cifra os dados usando DataProtectionScope.CurrentUser. 
                // O resultado pode ser decifrado somente pelo mesmo usuário atual
                return ProtectedData.Protect(dados, _entropiaAdicional, DataProtectionScope.CurrentUser);
            }
            catch (CryptographicException e)
            {
                WriteLine("Os dados não foram cifrados/protegidos. Ocorreu um erro.");
                WriteLine(e.ToString());
                return null;
            }
        }
        public static byte[] Desprotege(byte[] dados)
        {
            try
            {
                //Decifra os dados usando DataProtectionScope.CurrentUser.
                return ProtectedData.Unprotect(dados, _entropiaAdicional, DataProtectionScope.CurrentUser);
            }
            catch (CryptographicException e)
            {
                WriteLine("Dados não foram decifrados... Ocorreu um erro.");
                WriteLine(e.ToString());
                return null;
            }
        }
        public static void ImprimeValores(Byte[] meuArray)
        {
            foreach (Byte i in meuArray)
            {
                Write("\t{0}", i);
            }
            WriteLine();
        }
    }
}

Vamos entender o código:

Iniciamos definindo o variável do tipo byte[] que é usado como entropia para geração do critografia.

            static byte[] _entropiaAdicional = { 9, 8, 7, 6, 5 };

O conceito de entropia está associada diretamente à imprevisibilidade, uu seja, entropia total você vai obter quando todos os bits de entropia forem realmente aleatórios (imprevisiveis). Então adicionamos um item para aumentar a imprevisibilidade.

A seguir definimos a variável que iremos criptografar, representada por um array de bytes

            byte[] segredo = { 0, 1, 2, 3, 4, 1, 2, 3, 4 };

Depois chamamos o método Protege() que vai usar o método Protect para criptograr os dados:

           ProtectedData.Protect(dados, _entropiaAdicional, DataProtectionScope.CurrentUser);

Aqui estamos passando os dados, a entropia e o escopo da criptografia definida como CurrentUser.

Para desproteger ou decifrar os dados que já foram criptografados chamamos o método Desprotege que usa o método Unprotect() e usa os dados , a entropia e o escopo definido:

           ProtectedData.Unprotect(dados, _entropiaAdicional, DataProtectionScope.CurrentUser);

Usamos o método ImprimeValores() para exibir os dados.

Executando o projeto teremos o resultado a seguir:

Pegue o código completo aqui:   CShp_ProtectedData1.zip

"Bem-aventurado o homem que não anda segundo o conselho dos ímpios, nem se detém no caminho dos pecadores, nem se assenta na roda dos escarnecedores.
Antes tem o seu prazer na lei do Senhor, e na sua lei medita de dia e de noite."

Salmos 1:1,2

 

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?


Referências:


José Carlos Macoratti