VB .NET - Criando código mais seguro
Quando você cria um aplicação não deve negligenciar um item fundamental mas muitas vezes deixado em segundo plano : a proteção do código , configurações e dados envolvidos na aplicação.
A proteção do seu código fonte assegura que seu trabalho intelectual não seja roubado a proteção dos dados tratados pela sua aplicação também é fundamental afinal você é o responsável pela aplicação e seu cliente vai querer que os dados que ela trate estejam seguros.
Neste artigo eu vou procurar dar em linhas gerais alguns procedimentos para tratar da proteção de uma aplicação : código fonte , dados e configuração. Quero entretanto deixar claro que você não deve tomar este artigo como a palavra final em segurança para aplicações . Ao contrário , ele é apenas uma introdução básica neste vasto e intrincado assunto muito em moda nos dias atuais : segurança.
1- Proteção de senhas e nomes de usuários
Nunca armazene senhas e nomes de usuários na forma de texto aberto. Aonde quer que você for armazenar senhas e chaves de usuários faça isto de forma mascarada via criptografia. Assim se alguém tiver acesso as senhas e nomes de usuários ele terá que ter o trabalho de decodificar a informação antes de usar. O VB .NET oferece recursos fáceis de usar para que este serviço seja feito.
Abaixo um exemplo onde um Hash é gerado para uma string informada:
Imports System.Security.CryptographyImports System.Text
Module Module1
Sub Main()
Dim SHA1HASHValue() As Byte Console.WriteLine("SHA1 HASH GENERATOR") Console.WriteLine("Entre com o texto a criptografar :") Dim sString As String = Console.ReadLine() 'Cria uma nova instância de UnicodeEncoding para 'converter a string em um array de bytes Unicode Dim UE As New UnicodeEncoding()'Converte o stringem um array de bytes. Dim MessageBytes As Byte() = UE.GetBytes(sString)'Cria uma instância de SHA1Managed para criar um valor hash Dim SHhash As New SHA1Managed()'Cria o valor hash SHA1HASHValue = SHhash.ComputeHash(MessageBytes) 'Exibe o valor hash value no console. Dim b As ByteFor Each b In SHA1HASHValue Console.Write("{0} ", b) Next b
Console.ReadLine() End Sub End Module |
O Hash gerado é um valor único de tamanho fixo representando uma quantidade de informação. Para o caso de senhas e chaves , se duas senhas ou chaves forem iguais elas irão gerar o mesmo Hash. Seu uso mais comum é nas assinaturas digitais e na integridade de dados.
Outra classe que pode ser usada para o mesmo objetivo é a classe - FormsAuthentication Class - que fornece métodos estáticos que podemos usar para gerenciar a autenticidade da informação. Seus membros principais relacionados com a segurança são:
Authenticate | Tenta validar a credencial contra aquela contida na credencial configurada na armazenagem. |
Decrypt | Retorna uma instância de uma classe FormsAuthenticationTicket , gerando um tiquete de autenticação criptografada de um cookie HTTP. |
Encrypt | Produz uma string contento um tiquete de autenticação criptografado adequado para usar com um cookie HTTP. |
Equals (inherited from Object) | Determina se dois objetos de instância são iguais. |
HashPasswordForStoringInConfigFile | Dada uma senha e uma string de identificando o tipo de hash gera uma senha hash adequada para ser armazenada no arquivo de configuração. |
Inicie um novo projeto no VS.NET do tipo Visual Basic modelo Windows e no formulário padrão inclua os controles conforme figura abaixo:
- O objetivo
é gerar um hash para uma senha informada
- Temos a opção de fazer a geração usando os algoritmos SHA1 ou MD5. |
O código associado ao evento - Click - do botão - Gerar Hash da Senha - é :
Private
Sub
GenerateHashButton_Click(ByVal
sender As
Object,
ByVal e
As System.EventArgs) Handles
GenerateHashButton.Click
Const SenhaVazia As String = "A informação da senha é obrigatória" Const SenhaNaoConfere As String = "A senha não confere" Const SenhaComBrancos As String = "A senha não pode iniciar nem terminar com espaços."
HashedPasswordTextBox.Text = ""
'verifica se as senhas informadas estão vazias. If PasswordTextBox.Text.Trim() = [String].Empty Or ConfirmPasswordTextBox.Text.Trim() = [String].Empty Then MessageBox.Show(SenhaVazia) PasswordTextBox.SelectAll() PasswordTextBox.Focus() Return End If
'verifica se não espaços em branco no inicio e no final da senha informada If PasswordTextBox.Text.StartsWith(" ") Or PasswordTextBox.Text.EndsWith(" ") ThenMessageBox.Show(SenhaComBrancos) PasswordTextBox.SelectAll() PasswordTextBox.Focus() Return End If
'verifica se as senhas são iguais If PasswordTextBox.Text <> ConfirmPasswordTextBox.Text ThenMessageBox.Show(SenhaNaoConfere) PasswordTextBox.SelectAll() PasswordTextBox.Focus() Return End If
'gera o hash e exibe na caixa de texto - HashedPasswordTextBox HashedPasswordTextBox.Text = FormsAuthentication.HashPasswordForStoringInConfigFile(PasswordTextBox.Text, HashingAlgorithmName) If ClipboardCopyCheckBox.Checked Then Clipboard.SetDataObject(HashedPasswordTextBox.Text, False) End If Return
End Sub |
A linha de código responsável pelo serviço é dada a seguir , o restante do código é somente validação:
HashedPasswordTextBox.Text = FormsAuthentication.HashPasswordForStoringInConfigFile(PasswordTextBox.Text, HashingAlgorithmName)
Nota: Outra forma de gerar um hash MD5 e usando o seguinte código:
Function HashMD5(Senha as string) as string Dim md5Hasher As New System.Security.Cryptography.MD5CryptoServiceProvider() Dim hashedBytes As Byte() Dim encoder As New System.Text.UTF8Encoding() Dim saida As String Dim b As Byte
hashedBytes = md5Hasher.ComputeHash(encoder.GetBytes(Senha)) For Each y In hashedBytes saida &= y Next y
HashMD5 = saidsa
End Function |
Podemos ainda usar o código a seguir . Para isto crie um novo projeto no VS.NET e no formulário padrão monte o layout conforme abaixo.
- No formulário basta instânciar a classe e
usar :
|
No menu Project selecione Add Class nomeando o arquivo como - clsCrypto.vb. Abaixo o código da classe - clsCrypto.vb.( Perceba que teremos acesso apenas ao método clsCrypto que é público.)
Imports System.Security.Cryptography
DES.Key = hashmd5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(myKey))
|
Eu nem estou considerando que você vá guardar chave e senha no seu código apenas pensando que por esta compilado eles vão estar protegidos. Qualquer usuário com as ferramentas adequadas pode decompilar (Disassembling) o seu código e você terá senha e nomes expostos.
Protegendo seu código da decompilação
Quando você compila seu código-fonte C# ou VB.NET o compilador vai convertê-lo para uma linguagem intermediária chamada - MSIL - Microsoft Intermediate Language - que é um conjunto de instruções em um tipo de assembly independente da CPU. Ao gerar o MSIL o compilador também gera metadados que são as informações embutidas no seu projeto que descrevem os tipos e suas definições , as assinaturas dos membros de cada tipo e outros dados.
Nota: Se você conhece Java já sacou o conceito. Afinal em java o código compilado gera um bytecode que pode ser executado em qualquer plataforma que possua uma máquina virtual - JVM .
Abaixo temos um esquema representando esta operação , a compilação e geração de código MSIL e a decompilação e geração de código C# :
A MSIL possui uma vasta gama de instruções para carregar , armazenar , inicializar , chamar métodos em objetos , operações lógicas , controles de fluxo , acesso direto a memória e manipulação de exceções. Antes do código poder ser executado a MSIL precisa ser convertida para o código da CPU do ambiente em que vai rodar ; isto é feito por compiladores Just in time (JIT) que converte o código para assembly nativo.
No final do processo você terá um arquivo PE (Portable Executable) que contém a MSIL e os metadados que irá rodar na CLR - Common Language RunTime. O problema é que , como foi abordado no artigo - Decompilando seu projeto VB.NET , o seu código pode ser decompilado usando ferramentas apropriadas.
Você não esta acreditando muito nesta história ? Pois vou mostrar que usando uma ferramenta da própria Microsoft - ISDASM.EXE - podemos expor o seu código fonte. Crie a seguinte classe em um projeto do tipo Console.
Class1.vb
imports system Namespace Macoratti class m shared sub main |
Após compilar este código teremos um arquivo executável de nome class1.exe. Abaixo uma figura onde estou exibindo as etapas seguidas para gerar e testar o arquivo class1.exe.
As etapas
seguidas para gerar e testar o arquivo class1.exe - O arquivo class1.vb criado no bloco de notas - a compilação do arquivo class1.vb : vbc class1.vb - o arquivo class1.exe gerado - a execução do arquivo class1.exe exibindo a mensagem |
Vamos agora usar o utilitário ILDASM para obter o código IL o qual é lido a partir do METADATA do assembly. Para isto basta digitar a seguinte linha de comando:
ILDASM Class1.exe /out=Class1.il |
Agora você pode dar uma espiada no arquivo class1.il gerado e poderá ver muito mais do que apenas bytes...
Você pode executar o utilitário ILDASM a partir do Windows . Ele geralmente esta na basta bin de FrameworkSDK na pasta onde você instalou o VS.NET. Veja abaixo a figura do ildasm.exe exibindo a class1.exe
Para obter mais detalhes sobre o código clique duas vezes sobre o item. Abaixo a figura exibindo detalhes do método main:
Acredita agora ??? Se com um simples utilitário Microsoft você conseguir tudo isto imagine com uma ferramenta especializada ????
Então eu pergunto : Existe alguma forma de proteção do código compilado sem ter que usar e pagar por ofuscadores de código de terceiros ?
Sim , existe uma forma de dificultar o processo. Você deve seguir os seguintes passos após gerar o seu executável - class1.exe.
ILDASM class1.exe /out=class1.il |
ILASM /owner=mac class1.il |
Desta forma o arquivo class1.exe criado com a chave owner=mac não poderá ser aberto usando o utilitário ILDASM , se alguém tentar vai obter a mensagem : "Copyrighted Material- can not disassemble"
Para conseguir é necessário saber a chave definida com owner :
ILDASM /owner=mac Class1.exe |
É claro que isto não vai proteger o seu código de forma definitiva mas já coloca uma barreira a mais a ser superada.
Sinceramente eu não uso arquivos UDL para fornecer dados para a string de conexão. Um arquivo UDL é um recurso externo a mais que você vai ter que proteger em sua aplicação . Se você estiver operando sob o NTFS pode até atribuir uma proteção de permissão de acesso a arquivo. Se não estiver , vai ter que procurar uma forma de esconder a informação do arquivo.
Mantenha - Persist Security Info - como False
Se você definir - Persist Security Info - como true ou yes , irá permitir que a chave e senha possam ser obtidas da conexão depois que a mesma for aberta. Se você estiver fornecendo chave e senha para abrir uma conexão esta informação deve ser usada e logo descartada. Para que isto ocorra defina - Persist Security Info - como False ou no.
Cuidado com strings de conexão criadas com entradas de usuário
Se você monta sua string de conexão a partir de uma informação fornecida pelo usuário ( senha e chave) você deve ter cuidado para ter certeza de que os valores usados para criar sua string de conexão não contenham informação extra que possam alterar o comportamento de sua conexão. Procure efetuar a validação da entrada do usuário verificando se o formato da string de conexão não será afetado.
As expressões regulares podem ser usadas para validar entradas de dados em um formato específico. O .NET Framework fornece o objeto Regex para validar um valor contra uma expressão. Para verificar se o valor de uma chave de usuário tem 8 caracteres alfanuméricos do tipo string podemos usar o código:
Imports
System.Text.RegularExpressionsPublic Static Function ValidarUsuario(inString As String) As Boolean Dim r As Regex = New Regex("^[A-Za-z0-9]{8}$") Return r.IsMatch(inString) End Function |
Até mais ...
João 5:24 Em verdade, em verdade vos digo que quem ouve a minha palavra, e crê naquele que me enviou, tem a vida eterna e não entra em juízo, mas já passou da morte para a vida.
João 5:25 Em verdade, em verdade vos digo que vem a hora, e agora é, em que os mortos ouvirão a voz do Filho de Deus, e os que a ouvirem viverão.
João 5:26 Pois assim como o Pai tem vida em si mesmo, assim também deu ao Filho ter vida em si mesmos;
João 5:27 e deu-lhe autoridade para julgar, porque é o Filho do homem.
Veja os
Destaques e novidades do
SUPER DVD VB (sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ? Veja mais sistemas completos para a plataforma .NET no Super DVD .NET , confira... Quer aprender C# ?? Chegou o Super DVD C# com exclusivo material de suporte e vídeo aulas com curso básico sobre C#. |
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
VB6 - Express-Test - Gerador de testes de avaliacao para estudantes