CRIPTOGRAFIA

ONBASS 15/07/2011 18:07:10
#379310
Fala galera, boa noite.. seguinte

Ainda tentando aprender .Net, porém ando preocupado quanto à segurança. tipo andei lendo sobre criptografia e tal, mas achei o assunto pouco avançado pra mim, nunca usei tal recurso.. nao sei nem por onde começar.. tipo..

Algum de voces poderia me mostrar um codigo bem simples, criptografar e descrptografar.. tipo quando acessar á base (mysql) ler a senha(criptografada) na base? só pra dar um start.. ae quem sabe eu começo entender melhor as matérias mais avançadas.. desde já agradeço
PROFESSOR 24/10/2011 19:02:35
#387617
Criptografia é uma ciência onde você [Ô]embaralha[Ô] uma informação até que a mesma não seja mais compreensível, mas mantendo um modelo que permite a reversão ao estado original. Ela vêm se desenvolvendo ao longo dos últimos séculos, e mais notadamente desde pouco antes do advento da 1ª Grande Guerra Mundial. Explicado o paradigma, vamos aos fatos.

Os caracteres [Ô]legíveis[Ô] utilizados na informática contam com todas as letras ocidentais, os números indianos e uma série de símbolos gráficos, como @, #, $ etc. Ao todo, a tabela possui 256 [Ô]chaves[Ô] e é chamada tabela ASCII (American Standard Code for Information Interchange ou tabela americana de códigos para troca de informações) e até os primórdios do Windows®, era nela que se baseavam a maioria dos algoritimos de cdriptografia.

Com o passar dos anos, e a evolução dos equipamentos, as rotinas de de-criptografia passaram á contar com ferramentas muito mais eficientes e, por conta disso, a adoção desses algoritimos passou á ser uma barreira muito fácil de ser quebrada. Com isso, adotou-se a conversão das informações em blocos binários, antes do [Ô]embaralhamento[Ô], ação que possibilitava á um único bloco (ou caractere) sofrer uma [Ô]mutação[Ô] em até 1024 possíveis. Além dessas [Ô]mutações[Ô], o resultante era então [Ô]compactado[Ô], utilizando algum dos algoritimos de compressão de dados (LHZ,GZIP etc). é claro, os algorítimos não poderiam gerar essa [Ô]mutação[Ô] de forma totalmente aleatória, pois se o fizessem, seria impossível depois recuperar a informação original. Assim surgiu a idéia de utilizar uma [Ô]tabela guia[Ô], que hoje se conhece como [Ô]chave de criptografia[Ô].

Derivando disso, você deve perceber que você mesmo pode gerar um algorítimo de criptografia simples, partindo do mesmo princípio. Mas isso seria, além de re-inventar a roda, meio inóquo, uma vez que os algoritimos disponíveis hoje já sofreram (e sofrem) bem mais [Ô]pancadas[Ô] que qualquer um que você venha á desenvolver. Seria, não menosprezando, [Ô]tirar o doce de uma criança[Ô], se mais tarde algum hacker pusesse as mãos na base de dados.

As metodologias para a composição de chaves de criptografia e para [Ô]embaralhamento[Ô] de frases evoluiram ao ponto de ganharem [Ô]adeptos[Ô] desta ou daquela metodologia, nomes que por si mesmos parecem saídas dos filmes de 007 (Blowfish, Twofish, WWII Germany, Navajo Code e outras) e até Holliwood entrou no assunto várias vezes.

Assim, e como o MySQL possui também um Membership Provider para o ASP.Net (veja no site da Oracle e no CodeProject), acho que seria oportuno usar as ferramentas que já existem. No site da Microsoft, assim como nos exemplos que vêm com o Visual Studio e seus pacotes, você encontra alguns exemplos de códigos.

E isso colocado, vamos á prática? Aqui eu apresento um exemplo para a Rjindael (SHA1).

... outros imports...
Imports System.Security
Imports System.Security.Cryptography
Imports System.IO
Imports System.Runtime.InteropServices
Imports System.Text.RegularExpressions
Imports System.Text

Public Class MyData
Implements IDisposable

[ô][ô][ô] <summary>
[ô][ô][ô] Criptografa um texto.
[ô][ô][ô] </summary>
[ô][ô][ô] <param name=[Ô]plainText[Ô]>Texto á criptografar.</param>
[ô][ô][ô] <returns>Texto criptografado.</returns>
[ô][ô][ô] <example>
[ô][ô][ô] <code>Dim strEncryptedText As String = Encrypt([Ô]MeuTexto[Ô])</code>
[ô][ô][ô] </example>
[ô][ô][ô] <remarks>Utiliza a Rjindael.</remarks>
Public Function Encrypt(ByVal plainText As String) As String
Dim passPhrase As String = [Ô]chavedecriptografia[Ô]
Dim saltValue As String = [Ô]ValorDeSalto[Ô]
Dim hashAlgorithm As String = [Ô]SHA1[Ô]
Dim passwordIterations As Integer = 2
Dim initVector As String = [Ô]@1B2c3D4e5F6g7H8[Ô] [ô]Veja que são 16 posições.
Dim keySize As Integer = 256
Dim initVectorBytes As Byte() = Encoding.ASCII.GetBytes(initVector)
Dim saltValueBytes As Byte() = Encoding.ASCII.GetBytes(saltValue)
Dim plainTextBytes As Byte() = Encoding.UTF8.GetBytes(plainText)
Dim password As New PasswordDeriveBytes(passPhrase, saltValueBytes, hashAlgorithm, passwordIterations)
Dim derivar As New Rfc2898DeriveBytes(passPhrase, saltValueBytes, passwordIterations)
Dim keyBytes As Byte() = derivar.GetBytes(keySize \ CInt(8))
Dim symmetricKey As New RijndaelManaged()
symmetricKey.Mode = CipherMode.CBC
Dim encryptor As ICryptoTransform = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes)
Dim memoryStream As New MemoryStream()
Dim cryptoStream As New CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length)
cryptoStream.FlushFinalBlock()
Dim cipherTextBytes As Byte() = memoryStream.ToArray()
memoryStream.Close()
cryptoStream.Close()
Dim cipherText As String = Convert.ToBase64String(cipherTextBytes)
Return cipherText
End Function
[ô][ô][ô] <summary>
[ô][ô][ô] De-criptografa um texto criptografado com a Rjindael.
[ô][ô][ô] </summary>
[ô][ô][ô] <param name=[Ô]cipherText[Ô]>Texto criptografado.</param>
[ô][ô][ô] <returns>Texto de-criptografado.</returns>
[ô][ô][ô] <example>
[ô][ô][ô] <code>Dim strDecrptedText As String = Decrypt(varTextoCriptografado)</code>
[ô][ô][ô] </example>
[ô][ô][ô] <remarks>Válido somente para as criptografias feitas com esta classe.</remarks>
Public Function Decrypt(ByVal cipherText As String) As String
Dim passPhrase As String = [Ô]chavedecriptografia[Ô]
Dim saltValue As String = [Ô]ValorDeSalto[Ô]
Dim hashAlgorithm As String = [Ô]SHA1[Ô]
Dim passwordIterations As Integer = 2
Dim initVector As String = [Ô]@1B2c3D4e5F6g7H8[Ô] [ô]Veja que são 16 posições.
Dim keySize As Integer = 256
Dim initVectorBytes As Byte() = Encoding.ASCII.GetBytes(initVector)
Dim saltValueBytes As Byte() = Encoding.ASCII.GetBytes(saltValue)
Dim cipherTextBytes As Byte() = Convert.FromBase64String(cipherText)
Dim password As New PasswordDeriveBytes(passPhrase, saltValueBytes, hashAlgorithm, passwordIterations)
Dim derivar As New Rfc2898DeriveBytes(passPhrase, saltValueBytes, passwordIterations)
Dim keyBytes As Byte() = derivar.GetBytes(keySize \ 8)
Dim symmetricKey As New RijndaelManaged()
symmetricKey.Mode = CipherMode.CBC
Dim decryptor As ICryptoTransform = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes)
Dim memoryStream As New MemoryStream(cipherTextBytes)
Dim cryptoStream As New CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read)
Dim plainTextBytes As Byte() = New Byte(cipherTextBytes.Length - 1) {}
Dim decryptedByteCount As Integer = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length)
memoryStream.Close()
cryptoStream.Close()
Dim plainText As String = Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount)
Return plainText
End Function
... a classe continua ...



Essas duas rotinas acima são bem simples, fáceis de implementar em qualquer situação, ainda que não são [Ô]invioláveis[Ô], de forma alguma. No caso, usando o MySql, você teria a seguinte situação, para exemplificar:

Gravação dos dados:

   ...
Dim cn As New MySqlcommand(ConfigurationManager.ConnectionStrings(0).ConnectionString)
Dim mCommand As MySqlCommand = cn.CreateCommand;
mCommand.CommandText = String.Format([Ô]INSERT INTO contatos (NOME, SENHA) ([ô]{0}[ô],[ô]{1}[ô])[Ô], txtNome.Text, MyData.Encrypt(txtSenha.Text))
mCommand.ExecuteNonQuery
...


Carga dos dados:

   ...
Public Enum LoginResponses
UserNotFound
PassNotMatch
Success
None
End Enum
...
Dim ok As LoginResponses = LoginResponses.PassNotMatch
Dim da As New MySqlDataAdapter(String.Format([Ô]SELECT NOME, SENHA FROM contatos WHERE NOME =[ô]{0}[ô], txtNome.Text,
ConfigurationManager.ConnectionStrings(0).ConnectionString)
Dim tb As New DataTable([Ô]temp[Ô])
da.Fill(tb)
If (tb.Rows.Count = 0)
ok = LoginResponses.UserNotFound
Else
For Each r As DataRow In tb.Rows
If MyData.Decrypt(r([Ô]Senha[Ô])) = txtSenha.Text Then
ok = LoginResponses.Success
Exit For
End If
Next
End If
...


E é isso... Se ajudar, valew!
Tópico encerrado , respostas não são mais permitidas