Desenvolvimento - C#
Criptografando dados com C#
O artigo mostra um exemplo muito fácil de se implementar com C# uma classe que encripta e desencripta dados.
por Everton José BenedictoHoje a segurança da informação está sendo muito importante para nós, temos que nos assegurar que o que enviamos para algum lugar, chegue sem que outra pessoa leiam e intendam o que está no conteúdo da mensagem, e quem receber a mensagem entenda com clareza o que você enviou. Para assegurar que ninguem leia a sua mensagem encriptamos a mensagem com uma chave unica (que geralmente é criada pelo emissor da mensagem) e um algoritmo de encriptação de dados (que citarei alguns ao decorrer do artigo). Este processo de encriptação de dados com uma chave única é chamado de “Criptográfia Simétrica”.
Tipo de algoritmos de Criptográfia Simétrica que são mais usados no mercado:
· Rijndael
· RC2
· DES
· TripleDES
Se você fizer pesquisa básica na internet para saber um pouco mais sobre cada um desses algoritmos de criptográfia é muito rápida e fácil, não vou focar muito em cima desses algoritmo pois não é o foco principal do artigo.
Vou mostra um exemplo muito fácil de se implementar com C# uma classe que encripta e desencripta dados. Abra o Visual Studio e crie um projeto Windows Forms Chamado Criptografia (se desejar criar o projeto com outro nome sinta-se a vontade), vamos adicionar ao projeto uma classe chamada Criptografia.cs implentar o seguinte código que está abaixo na listagem 1.
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;
namespace Criptografia
{
/// <summary>
/// Enumerator com os tipos de classes para criptografia.
/// </summary>
public enum CryptProvider
{
/// <summary>
/// Representa a classe base para implementações criptografia dos algoritmos simétricos Rijndael.
/// </summary>
Rijndael,
/// <summary>
/// Representa a classe base para implementações do algoritmo RC2.
/// </summary>
RC2,
/// <summary>
/// Representa a classe base para criptografia de dados padrões (DES - Data Encryption Standard).
/// </summary>
DES,
/// <summary>
/// Representa a classe base (TripleDES - Triple Data Encryption Standard).
/// </summary>
TripleDES
}
public class Criptografia
{
#region Variáveis e Métodos Privados
private string _key = string.Empty;
private CryptProvider _cryptProvider;
private SymmetricAlgorithm _algorithm;
/// <summary>
/// Inicialização do vetor do algoritmo simétrico
/// </summary>
private void SetIV()
{
switch (_cryptProvider)
{
case CryptProvider.Rijndael:
_algorithm.IV = new byte[] { 0xf, 0x6f, 0x13, 0x2e, 0x35, 0xc2, 0xcd, 0xf9, 0x5, 0x46, 0x9c, 0xea, 0xa8, 0x4b, 0x73, 0xcc };
break;
default:
_algorithm.IV = new byte[] { 0xf, 0x6f, 0x13, 0x2e, 0x35, 0xc2, 0xcd, 0xf9 };
break;
}
}
#endregion
#region Properties
/// <summary>
/// Chave secreta para o algoritmo simétrico de criptografia.
/// </summary>
public string Key
{
get { return _key; }
set { _key = value; }
}
#endregion
#region Constructors
/// <summary>
/// Contrutor padrão da classe, é setado um tipo de criptografia padrão (Rijndael).
/// </summary>
public Criptografia()
{
_algorithm = new RijndaelManaged();
_algorithm.Mode = CipherMode.CBC;
_cryptProvider = CryptProvider.Rijndael;
}
/// <summary>
/// Construtor com o tipo de criptografia a ser usada Você pode escolher o tipo pelo Enum chamado CryptProvider.
/// </summary>
/// <param name="cryptProvider">Tipo de criptografia.</param>
public Criptografia(CryptProvider cryptProvider)
{
// Seleciona algoritmo simétrico
switch(cryptProvider)
{
case CryptProvider.Rijndael:
_algorithm = new RijndaelManaged();
_cryptProvider = CryptProvider.Rijndael;
break;
case CryptProvider.RC2:
_algorithm = new RC2CryptoServiceProvider();
_cryptProvider = CryptProvider.RC2;
break;
case CryptProvider.DES:
_algorithm = new DESCryptoServiceProvider();
_cryptProvider = CryptProvider.DES;
break;
case CryptProvider.TripleDES:
_algorithm = new TripleDESCryptoServiceProvider();
_cryptProvider = CryptProvider.TripleDES;
break;
}
_algorithm.Mode = CipherMode.CBC;
}
#endregion
#region Public methods
/// <summary>
/// Gera a chave de criptografia válida dentro do array.
/// </summary>
/// <returns>Chave com array de bytes.</returns>
public virtual byte[] GetKey()
{
string salt = string.Empty;
// Ajusta o tamanho da chave se necessário e retorna uma chave válida
if (_algorithm.LegalKeySizes.Length > 0)
{
// Tamanho das chaves em bits
int keySize = _key.Length * 8;
int minSize = _algorithm.LegalKeySizes[0].MinSize;
int maxSize = _algorithm.LegalKeySizes[0].MaxSize;
int skipSize = _algorithm.LegalKeySizes[0].SkipSize;
if (keySize > maxSize)
{
// Busca o valor máximo da chave
_key = _key.Substring(0, maxSize / 8);
}
else if (keySize < maxSize)
{
// Seta um tamanho válido
int validSize = (keySize <= minSize) ? minSize : (keySize - keySize % skipSize) + skipSize;
if (keySize < validSize)
{
// Preenche a chave com arterisco para corrigir o tamanho
_key = _key.PadRight(validSize / 8, "*");
}
}
}
PasswordDeriveBytes key = new PasswordDeriveBytes(_key, ASCIIEncoding.ASCII.GetBytes(salt));
return key.GetBytes(_key.Length);
}
/// <summary>
/// Encripta o dado solicitado.
/// </summary>
/// <param name="plainText">Texto a ser criptografado.</param>
/// <returns>Texto criptografado.</returns>
public virtual string Encrypt(string texto)
{
byte[] plainByte = Encoding.UTF8.GetBytes(texto);
byte[] keyByte = GetKey();
// Seta a chave privada
_algorithm.Key = keyByte;
SetIV();
// Interface de criptografia / Cria objeto de criptografia
ICryptoTransform cryptoTransform = _algorithm.CreateEncryptor();
MemoryStream _memoryStream = new MemoryStream();
CryptoStream _cryptoStream = new CryptoStream(_memoryStream, cryptoTransform, CryptoStreamMode.Write);
// Grava os dados criptografados no MemoryStream
_cryptoStream.Write(plainByte, 0, plainByte.Length);
_cryptoStream.FlushFinalBlock();
// Busca o tamanho dos bytes encriptados
byte[] cryptoByte = _memoryStream.ToArray();
// Converte para a base 64 string para uso posterior em um xml
return Convert.ToBase64String(cryptoByte, 0, cryptoByte.GetLength(0));
}
/// <summary>
/// Desencripta o dado solicitado.
/// </summary>
/// <param name="cryptoText">Texto a ser descriptografado.</param>
/// <returns>Texto descriptografado.</returns>
public virtual string Decrypt(string textoCriptografado)
{
// Converte a base 64 string em num array de bytes
byte[] cryptoByte = Convert.FromBase64String(textoCriptografado);
byte[] keyByte = GetKey();
// Seta a chave privada
_algorithm.Key = keyByte;
SetIV();
// Interface de criptografia / Cria objeto de descriptografia
ICryptoTransform cryptoTransform = _algorithm.CreateDecryptor();
try
{
MemoryStream _memoryStream = new MemoryStream(cryptoByte, 0, cryptoByte.Length);
CryptoStream _cryptoStream = new CryptoStream(_memoryStream, cryptoTransform, CryptoStreamMode.Read);
// Busca resultado do CryptoStream
StreamReader _streamReader = new StreamReader(_cryptoStream);
return _streamReader.ReadToEnd();
}
catch
{
return null;
}
}
#endregion
}
}
Listagem 1: Classe Criptográfia
Coloquei comentários no código que exclarecem possiveis dúvidas. Depois de criar a classe Criptografia.cs vá no Form1 que é criado automáticamente com o projeto Windows Forms e faça uma tela com a layout que você pode visualizar na Figura 1.
Figura 1: Layout da Tela Criptografia.
Vamos renomear o nome dos componentes para não haver erros de compilação no seu código:
· TextBox (Texto Normal) : mude o nome para “txtNormal”.
· TextBox (Texto Criptografado) : mude o nome para “txtCriptografado” e coloque a propriedade Enabled para False.
· Button (Criptografar) : mude o nome para “btnCriptografar”.
· Button (Decriptar) : mude o nome para “btnDecriptar”.
Depois de ter configurado as propriedades dos componentes da tela vamos criar um evento para o botão “btnCriptografar” e colocar o seguinte código que está abaixo na Listagem 2.
private void btnCriptografar_Click(object sender, EventArgs e)
{
string texto = txtNormal.Text;
string key = "Criptografia"; //Está chave você mesmo é quem escolhe.
Criptografia crip = new Criptografia(CryptProvider.DES);
crip.Key = key;
txtCriptografado.Text = crip.Encrypt(texto);
}
Listagem 2: Evento do botão “btnCriptografar”.
Vamos criar agora o Evento para o botão “btnDecriptar” coloque o código que está na Listagem 3.
private void btnDecriptar_Click(object sender, EventArgs e)
{
string texto = txtCriptografado.Text;
//Está chave tem que ser a mesma que a do texto Encriptado.
string key = "Criptografia";
Criptografia crip = new Criptografia(CryptProvider.DES);
crip.Key = key;
MessageBox.Show(crip.Decrypt(texto), this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
}
Listagem 3: Evento do botão “btnDecriptar”.
Compile e execute o projeto. Digite uma frase qualquer e clique no botão “Criptografar”, ele colocará o texto criptografado no TextBox ao lado dele, agora se você clicar no botão “Decriptar” ele vai apresentar o texto decriptado no pop-up.
Conclusão
Criptográfia é muito importante para a nossa segurança de informação, e o exemplo que está no artigo é somente para que você consiga ter uma ideia de como funciona estas classes de criptografia da .Net. Você pode usar este código do exemplo para salvar senhas no banco de dados, dados que não podem ser vistos por outras pessoas, encriptar conteudo de arquivos textos, etc.
Editado por: Everton José Benedicto.