DUVIDA SOBRE CRYPTOGRAFIA

LUIS.HERRERA 29/03/2012 12:07:04
#398670
Estou estudando o assunto para criar duas rotinas de cryptografia no meu sistema, uma Hash para proteger as senhas dos usuários no banco e outra que deverá ter Encripty e Decripty do texto passado.

Bem a dúvida é sobre a forma de gerar a criptografia, ví muitos códigos na Web (MD5, SHA1(256, 384, 512 e 1024 bits), sendo que cada um deles de diversas formas diferentes. Alguns tem IV outros não, sendo um arrays de valores que não sei de onde vieram e o que significam exatamente.

Porém o que mais me deixou confuso, foi ler que a criptografia no .Net pode ser por usuário, por máquina, por Windows e por Rede. Então não entendi nada.

1) Como vou ter certeza que a criptografia feita por um usuário, poderá ser revertida por outro que tenha permissão, se usar um micro, um login ou um Windows diferente? Onde isso é configurado e como controlar?

Isso sendo possível até seria interessante ter uma rotina onde o usuário pudesse criptografas dados pessoais, que só ele pudesse reverter.

2) Como eu posso saber qual será o tamanho final de uma criptografia, seja Hash ou não, de modo a ter o campo de tamanho correto no banco de dados?
Pergunto porque vejo que alguns códigos, apesar do texto original ter tamanhos diferentes, alguns sempre dão o resultado com o mesmo comprimento da string, outros com textos pequenso retornam strings grandes e outros com textos grandes, retornam textos pequenos. Outros ainda retornam textos de tamanhos diferentes a cada criptografia.
KERPLUNK 29/03/2012 13:48:51
#398685
Resposta escolhida
Classe para criptografia:
public static class EncryptionHelper
{

//Esta é a senha de encriptação. Está hardcoded, mas você pode fazer
//da maneira que quiser, gravar em outro arquivo, no registro, buscar de
//webservice... fica à seu critério
private const string cryptoKey = [Ô]ChaveCriptografia[Ô];


private static readonly byte[] IV =
new byte[8] { 240, 3, 45, 29, 0, 76, 173, 59 };

public static string Encrypt(string s)
{
if (s == null || s.Length == 0) return string.Empty;

string result = string.Empty;

try
{
byte[] buffer = Encoding.ASCII.GetBytes(s);

TripleDESCryptoServiceProvider des =
new TripleDESCryptoServiceProvider();

MD5CryptoServiceProvider MD5 =
new MD5CryptoServiceProvider();

des.Key =
MD5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(cryptoKey));

des.IV = IV;
result = Convert.ToBase64String(
des.CreateEncryptor().TransformFinalBlock(
buffer, 0, buffer.Length));
}
catch
{
throw;
}

return result;
}

public static string Decrypt(string s)
{
if (s == null || s.Length == 0) return string.Empty;

string result = string.Empty;

try
{
byte[] buffer = Convert.FromBase64String(s);

TripleDESCryptoServiceProvider des =
new TripleDESCryptoServiceProvider();

MD5CryptoServiceProvider MD5 =
new MD5CryptoServiceProvider();

des.Key =
MD5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(cryptoKey));

des.IV = IV;

result = Encoding.ASCII.GetString(
des.CreateDecryptor().TransformFinalBlock(
buffer, 0, buffer.Length));
}
catch
{
throw;
}

return result;
}
}


Para usar:
string encriptado = EncryptionHelper.Encrypt([Ô]O que eu quiser encriptado[Ô]);

string decriptado = EncryptionHelper.Decrypt(encriptado);
KERPLUNK 29/03/2012 13:56:49
#398686
Respondendo às suas perguntas:
1 - A encriptação, depende basicamente de uma senha. Se a mesma senha for especificada para a encriptação e decriptação, não terá problemas
2 - O tamanho da string gerada, vai depender do conteúdo a ser encriptado. Às vezes, uma simples vírgula, muda o calculo completamente, gerando strings maiores ou menores

Quando ao HASH:
Toda e qualquer string pode-se gerar um código HASH, mas ele não é reversível. Um método muito comum é para senhas. Quando você grava a senha no banco, ao invés de gravar uma string, é gravado o HASH e se fornece uma função que retorna um boolean, dizendo se a senha é ou não aquilo que foi passado:
Senha gravada no banco: ABCD
Para saber se a senha está correta: ChecarSenha([Ô]SENHA[Ô])
A função checar senha, cria o hash do valor(ou faz qualquer outra função interna encripta o valor) [Ô]SENHA[Ô] e verifica se o valor é o mesmo que está no campo, caso seja, ele retorna um true, senão, false
Isso se faz para a senha nunca aparecer no banco e para que não existe uma função que [Ô]reverte[Ô] a senha encriptada de volta para o valor original, pelo menos não visivelmente.
LUIS.HERRERA 29/03/2012 15:25:19
#398700
Grande Kerplunk, boa tarde.
Ok entendi.

Fui testar seu código e quando uso acentos, ele coloca ? na hora de descriptografar, como resolver isso?
KERPLUNK 29/03/2012 16:39:29
#398709
Este código, usa a classe ASCII para gerar os buffers para encriptação, experimente usar a classe Default. Substitua tudo que for [Ô]ASCII[Ô] para [Ô]Default[Ô].
A classe ASCII, usa obviamente a tabela ASCII para criar um array com o código ASCII de cada caracter mas não leva em conta internacionalização. Acho que se usar o Default(a página de códigos que o sistema operacional use), isso deve ser solucionado.
LUIS.HERRERA 29/03/2012 16:44:28
#398711
Perfeito.

Obrigado.
Tópico encerrado , respostas não são mais permitidas