terça-feira, setembro 11, 2007

Encriptar com o DES em C#

Já algum tempo que não mexia com bibliotecas criptográficas e como até sou um bocado esquecido, tive de pesquisar um bocado até chegar a uma solução que me fizesse encriptação com o DES. O código resultante foi o seguinte:
//DES Provider
DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
DES.Key = ASCIIEncoding.ASCII.GetBytes(ConfigurationManager.AppSettings["DESKey"]);
DES.IV = ASCIIEncoding.ASCII.GetBytes(ConfigurationManager.AppSettings["DESIV"]);
//DES encriptor
MemoryStream memoryStream = new MemoryStream();
ICryptoTransform desencrypt = DES.CreateEncryptor();
CryptoStream cryptoStream = new CryptoStream(memoryStream, desencrypt, CryptoStreamMode.Write);
 //Data to encript
StreamWriter writer = new StreamWriter(cryptoStream);
writer.Write("UmaQualquerPassword");
writer.Flush();
cryptoStream.FlushFinalBlock();
writer.Flush();
//encriptor return
string password = Convert.ToBase64String(memoryStream.GetBuffer(), 0, (int)memoryStream.Length)
Depois de fazer isto a solução não me agradou, acho que é código demais para fazer uma simples encriptação de uma string. 1) Porquê são necessários dois streams, um de entrada e um de saída? 2) Porquê é necessário um terceiro stream para escrever para o cripto CryptoStream?
1) Em conversa com um amigo a explicação que ele arranjou foi: O objectivo é tornar as bibliotecas genéricas. Eu até aceito esta explicação, mas não concordo muito que se complique a usabilidade das bibliotecas só para as tornar genéricas.
2) É necessário um terceiro stream porque o CryptoStream não tem um método de Write que seja simples de utilizar ao contrário do método de Write do StreamWriter.
Para mim a encriptação deveria ser algo tão simples como algo do género:
//DES Provider
DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
DES.Key = ASCIIEncoding.ASCII.GetBytes(ConfigurationManager.AppSettings["DESKey"]);
DES.IV = ASCIIEncoding.ASCII.GetBytes(ConfigurationManager.AppSettings["DESIV"]);
//DES encriptor
MemoryStream memoryStream = new MemoryStream();
ICryptoTransform desencrypt = DES.CreateEncryptor();
string password = desencrypt.Transform("UmaQualquerPassword");
Continuava a ser genérico, bastando que a interface ICryptoTransform tivesse um método Transform de jeito, útil para estas situações simples onde só se quer encriptar uma string.

3 comentários:

Unknown disse...

Esquece o DES. Pensa em AES.
Dica: usa o BouncyCastle para C#.

Tiago Sousa disse...

Tenho mesmo que usar o DES porque o serviço que estou a utilizar descodifica com o DES a informação que lhe mando. De qualquer modo obrigado pela dica vou investigar melhor porque não conheço.

Vlad disse...

Head... hurts... back... to... design...