ATPS Desenvolvimento de Sotware Seguro
-
Upload
antonioarantesarantes -
Category
Documents
-
view
29 -
download
0
description
Transcript of ATPS Desenvolvimento de Sotware Seguro
UNIVERSIDADE ANHANGUERA-UNIDERP
UNIVERSIDADE ANHANGUERA – UNIDERP
CENTRO DE EDUCAÇÃO A DISTÂNCIA
CURSO DE TÉCNOLOGIA EM ANÁLISE E DESENVOLVIMENTO DE
SISTEMAS
DESENVOLVIMENTO DE SOFTWARE SEGURO
Nome RA
1 - Antônio Arantes Carvalho RA: 6787399445
2 - Dione Schmidt RA: 7512583119
3 - Erico Nobrega Cecílio RA: 7566611984
4 - Fábio Rodrigues Vian RA: 6954466415
5 – Marco Antonio Diniz dos Santos Reis RA: 1299767305
6 - Rodrigo Vieira Correard RA: 7718627339
Atividade Prática Supervisionada
(ATPS) entregue como requisito para
conclusão da disciplina
“Desenvolvimento de Software
Seguro”, sob orientação do professor-
tutor a distância Walter Gima
POLO PINDAMONHANGABA
2015
1
UNIVERSIDADE ANHANGUERA-UNIDERP
SUMÁRIO
DESAFIO 2
OBJETIVO............................................................................................................2
ETAPA 1 - PASSO 1............................................................................................3
ETAPA 1 - PASSO 2............................................................................................4
ETAPA 1 - PASSO 3............................................................................................5
ETAPA 2 - PASSO 1............................................................................................6
ETAPA 2 - PASSO 2............................................................................................6
ETAPA 2 - PASSO 3............................................................................................7
ETAPA 3 - PASSO 1............................................................................................8
ETAPA 3 - PASSO 2............................................................................................9
ETAPA 4 - PASSO 1..........................................................................................11
ETAPA 4 - PASSO 2..........................................................................................11
ETAPA 4 - PASSO 3..........................................................................................11
Referências bibliográficas...................................................................................12
DESAFIO
Uma empresa de desenvolvimento de software sofreu diversos ataques em seus
sistemas de informações, esses ataques causaram vários prejuízos materiais, comprometendo
sua credibilidade no mercado de softwares. Para corrigir as falhas de segurança dos sistemas,
essa empresa contratou uma equipe de consultores para auxiliá-la.
Você e sua equipe foram contratados para identificar e corrigir possíveis falhas de segurança
nos sistemas da empresa e implantar os conceitos de desenvolvimento de software seguro
desde as primeiras fases de criação de seus Sistemas de Informações.
2
UNIVERSIDADE ANHANGUERA-UNIDERP
RELATÓRIO 01 – DESENVOLVENDO SOFTWARE SEGURO
1.1 Passo 1 (A necessidade de investir em segurança no desenvolvimento de sistemas) 4
1.2 Passo 2 (Princípios de Segurança) 5
RELATÓRIO 02 – EVITANDO ESTOURO DE BUFFER 6
2.1 Breve História 6
2.2 Buffer Overflow 7
2.3 Stack Buffer Overflow 7
2.4 Heap Buffer Overflow 7
2.5 Off-by-One erros 8
2.6 Return-to-libc attack 8
2.7 Exemplo de estouro de buffer 9
2.8 Evitando o estouro de buffer 10
2.8.1 Escrever código seguro 10
2.8.2 Invalidar a execução de código na pilha 10
2.8.3 Ferramentas do Compilador 11
2.8.4 Verificações na altura da execução 11
2.8.5 Runtime dinâmica 12
RELATÓRIO 03 – UTILIZANDO CRIPTOGRAFIA 12
3.1 Base64 - Conceito 12
3.2 MD5 - Conceito 13
3.3 SHA1 - Conceito 13
3.4 Base64 – Na linguagem PHP 14
3.5 MD5 – Na linguagem PHP 14
3.6 SHA1 – Na Linguagem PHP 14
3.7 Base64 – Na Linguagem Java 15
3
UNIVERSIDADE ANHANGUERA-UNIDERP
3.8 SHA1 – Na Linguagem Java 15
3.9 MD5 – Na Linguagem Java 15
3.10 Base64 – Na Linguagem ASP 16
3.11 MD5 – Na Linguagem ASP 19
3.12 SHA1 – Na Linguagem ASP 19
3.12 Conclusão – Comparação entre os métodos 20
BIBLIOGRAFIA 21
RELATÓRIO 01 – DESENVOLVENDO SOFTWARE SEGURO
1.1 Passo 1 (A necessidade de investir em segurança no desenvolvimento de sistemas)
A falta de segurança em projetos de software é uma das principais preocupações das
organizações. É por meio das vulnerabilidades presentes em projetos de software que ocorre a
quebra de sigilo e roubo de informações. Devido a esse fator, as organizações estão buscando
adotar medidas cada vez mais rigorosas de proteção alinhadas às normas e metodologias de
segurança (BRAZ, 2009).
As ameaças à segurança das informações dos negócios, de propriedade intelectual e a
privacidade das informações pessoais estão aumentando. Assim, a necessidade de conter tais
ameaças, presentes a cada dia, faz com que o gerenciamento da segurança de informações
ganhe mais importância nas empresas. De acordo com um estudo realizado pela McAfee
(MCAFEE, 2009), o roubo de dados e violações de crimes cibernéticos pode ter custado para
as empresas, em 2008 mais que U$ 1 trilhão em razão da perda de propriedade intelectual e
com gastos com reparação dos prejuízos. Se esses dados pudessem ser previstos certamente
poderiam ter sido evitados através da implementação de alguns modelos de segurança como:
ISO27001, ISO27002, SSE-CMM, entre outros; como indicado por (WAGNER, 2011).
Diante dessa demanda por Sistemas Informatizados, grande parte das empresas recorre à
contratação de Software Houses para desenvolvimento de seus sistemas, sendo estes críticos,
ou que estão intimamente ligados a outros sistemas críticos à operação da organização. Muitas
vezes, existe a necessidade pela exposição externa dos dados para parceiros e clientes através
da Internet. Cresce também a importância com a necessidade da segurança da informação,
visando proteger a informação contra os vários tipos de agentes ameaçadores, e com isto
procura - seminimizar os riscos ao negócio e garantir que a informação se mantenha íntegra,
4
UNIVERSIDADE ANHANGUERA-UNIDERP
para maximizar o retorno sobre os investimentos. Cruz, 2007 defende que é necessário se
preocupar com a segurança desde o desenvolvimento de softwares, com o objetivo de garantir
integridade e confiabilidade das informações. A cada dia está sendo mais necessário o
desenvolvimento de sistemas com menor probabilidade a falhas e com um nível maior de
segurança.
1.2 Passo 2 (Princípios de Segurança)
Uma solução de segurança adequada deve satisfazer os seguintes princípios:
Confidencialidade: Proteger informações contra sua revelação para alguém não autorizado
(interna ou externamente) e leitura e/ou cópia não autorizado. A informação deve ser
protegida independentemente da mídia que a contenha (mídia impressa ou digital). Deve-se
cuidar não apenas da proteção da informação como um todo, mas também de partes da
informação que podem ser utilizadas para interferir sobre o todo. No caso da rede, isto
significa que os dados, enquanto em trânsito, não serão vistos, alterados ou extraídos da rede
por pessoas não autorizadas.
Integridade: A integridade consiste em proteger a informação contra modificação sem a
permissão explícita do proprietário daquela informação. A modificação inclui ações como
escrita, alteração de conteúdo, alteração de status, remoção e criação de informações. Deve-se
considerar a proteção da informação nas suas mais variadas formas, como por exemplo,
armazenada em discos ou fitas de backup. Integridade significa garantir que se o dado está lá,
então não foi corrompido, encontra-se íntegro. Isto significa que aos dados originais nada foi
acrescentado, retirado ou modificado. A integridade é assegurada evitando-se alteração não
detectada de mensagens e o forjamento não detectado de mensagem (aliado à violação de
autenticidade).
Disponibilidade: Consiste na proteção dos serviços prestados pelo sistema de forma que eles
não sejam degradados ou se tornem indisponíveis sem autorização, assegurando ao usuário o
acesso aos dados sempre que deles precisar. Isto pode ser chamado também de continuidade
dos serviços. Diz respeito à eficácia do sistema, ao correto funcionamento da rede para que
quando a informação for necessária ela poderá ser acessada.
5
UNIVERSIDADE ANHANGUERA-UNIDERP
Autenticidade: O controle de autenticidade está associado com identificação correta de um
usuário ou computador. O serviço de autenticação em um sistema deve assegurar ao receptor
que a mensagem é realmente procedente da origem informada em seu conteúdo. A verificação
de autenticidade é necessária após todo processo de identificação, seja de um usuário para um
sistema, de um sistema para o usuário ou de um sistema para outro sistema. Ela é a medida de
proteção de um serviço/informação contra a personificação por intrusos.
Não-Repúdio: É a garantia de que um agente não consiga negar um ato ou documento de sua
autoria. Essa garantia é condição necessária para a validade jurídica de documentos e
transações digitais. Não-Repúdio só é garantido quando houver Autenticidade e Integridade.
RELATÓRIO 02 – EVITANDO ESTOURO DE BUFFER
2.1 Breve História
A documentação mais antiga de Buffer Overflow data de 1988. Foi uma das muitas
vulnerabilidades exploradas pelo Morris worm para se propagar pela internet. O programa-
alvo foi um serviço Unix, chamado finger. Em 1995, Thomas Lopatic redescobriu sozinho o
buffer overflow e publicou seusachados na lista de e-mails da Bugtraq. Um ano depois, Elias
Levy (também conhecido como Aleph One), publicou na revista Phrack, o artigo “Smashing
the Stack for Fun and Profit” (Arrasando a Pilha por Diversão e Lucro), uma introdução
passo-a-passo para realizar um stack-based buffer overflow.
Desde então, pelo menos 2 worms exploraram buffer overflows para comprometer um
número grande de sistemas. Em 2001, o Code Red Worm explorou um buffer overflow no
ISS (Internet Information Services) 5.0 da Microsoft e em 2003, o worm SQL Slammer
colocou em risco máquinas rodando Microsoft SQL Server 2000.
2.2 Buffer Overflow
O buffer overflow é a forma de ataque baseado na exploração do mal uso de funções que
manipulam arrays. Esta vulnerabilidade pode estar presente em linguagens que não verificam
automaticamente se os limites de memória alocada para uma variável foram respeitados
durante a execução do programa.
Podem resultar em execução errônea de um programa, acesso indevido às áreas de memória,
terminação do programa ou uma possível falha de segurança em um sistema.
6
UNIVERSIDADE ANHANGUERA-UNIDERP
A seguir serão apresentados alguns exemplos de estouro de buffer.
2.3 Stack Buffer Overflow
Ocorre quando certa quantidade de dados copiados para a estrutura é maior que o buffer
declarado sobrescrevendo dados ali existentes. Isso acontece devido a não verificação através
de funções que validam o tamanho da informação antes de adicioná-la. Sendo assim, a melhor
forma de evitar esse problema seria sempre validar todas as entradas do programa, proteger
código utilizando o encapsulamento, por exemplo, onde as variáveis destinadas a determinada
função seja utilizada somente por ela.
Bibliotecas de tipos de dados abstratos bemescritas e testadas que centralizam e checam
automaticamente o gerenciamento de buffer, incluindo checar os limites, podem reduzir a
ocorrência e impacto de estouros de buffer.
2.4 Heap Buffer Overflow
Um heap overflow é um tipo de buffer overflow que ocorre na heap. Overflows na heap são
explorados de maneira diferente de overflows na pilha (stack overflow). Os dados na heap são
alocados dinamicamente pela aplicação, em tempo de execução, e tipicamente, contém dados
do programa. A exploração é feita corrompendo estes dados de uma maneira específica para
causar sobrescrita em estruturas internas da aplicação, como listas de ponteiros.
Em regra, a técnica de heap overflow sobrescreve links da memória de alocação dinâmica e
substitui por um ponteiro de função de chamada de um programa.
O sistema operacional Microsoft Windows implementa proteções contra heap overflow
desde Windows XP SP2. Ele também pode atenuar essas ameaças através da utilização de
Data Execution Prevention (DEP).
2.5 Off-by-One erros
Um erro off-by-one, também conhecido como um OBOB (off-by-one bug), é um erro de
lógica que envolve uma condição de contorno. Muitas vezes ocorre, quando um ciclo repete
tempo demais ou muito pouco. Este problema pode surgir quando um programador comete
erros, tais como a utilização de "é menor ou igual a" onde "é menor do que" deve ter sido
usado em uma comparação ou falha em ter em conta que uma sequência começa em zero uma
7
UNIVERSIDADE ANHANGUERA-UNIDERP
vez que isto também pode ocorrer em um contexto matemático.
Um erro comum off-by-one que resulta em um bug relacionado com a segurança é causada
por mau uso da biblioteca padrão C strncat. Um equívoco comum com strncat é que o
encerramento nulo garantido que não vaiescrever para além do comprimento máximo. Na
realidade, ele vai escrever um nulo e um byte encerra além do comprimento máximo
especificado.
Uma abordagem que muitas vezes ajuda a evitar esses problemas é a utilização de variantes
destas funções que calcula o quanto de gravação com base no comprimento total do buffer,
em vez de o número máximo de caracteres para escrever. Essas funções
incluem strlcat e strlcpy, e são muitas vezes consideradas "mais seguras", porque eles tornam
mais fáceis evitar que acidentalmente se escreva, passando do fim do buffer.
2.6 Return-to-libc attack
É um ataque à segurança do computador, que usualmente inicia com um buffer overflow em
que o endereço de retorno da função chamada na pilha é substituído pelo endereço de outra
instrução, e uma parte da pilha é sobrescrita para fornecer argumentos para está função. Isto
permite que o atacante invoque uma função preexistente sem precisar injetar código malicioso
no programa.
Uma pilha não executável pode impedir alguns ataques de buffer overflow, no entanto, não
pode impedir um ataque return-to-libc, porque nesse ataque somente o código executável já
existente é utilizado. Por outro lado, esses ataques só podem chamar funções pré-
existente. Stack-smashing protection pode evitar ou impedir esse tipo de ataque, já que ele
detecta a corrupção da pilha e, possivelmente, eliminar o segmento comprometido.
2.7 Exemplo de estouro de buffer
Na função a seguir temos um exemplo de estouro de buffer.
Void function (int a, int b, int c)
{char buffer1[5];
char buffer2 [10];
}
8
UNIVERSIDADE ANHANGUERA-UNIDERP
int main() { function(1,2,3);
}
O buffer1 ocupa 8 bytes e o buffer2 12, pois a memória só pode ser endereçada em múltiplos
de words (4 bytes).Um FP é necessário para aceder às variáveis a, b, c, buffer1 e buffer2.
Todas estas variáveis são limpas após a execução da função e não ocupam espaço no ficheiro
executável do programa.
void function (char *str) {
char buffer[16];
strcpy (buffer, str);
}
int main () {
char *str = "Eu sou maior do que 16 bytes"; // tamanho da string 28 bytes function (str);
}
Este programa causa garantidamente comportamento inesperado, uma vez que uma string, str,
de 28 bytes foi copiada para uma localização de apenas 16 bytes (função strcpy). Os bytes
extras ultrapassam o buffer e reescrevem o espaço alocado para o FP, endereço de retorno,
etc. Isto por sua vez corrompe a stack ou pilha do processo. A função usada para copiar a
string é a strcpy, que não faz a verificação dos limites. Usar a função strncpy como substituta
ajuda a prevenir o problema.
2.8 Evitando o estouro de buffer
As soluções propostas para este tipo de problemas visam, sobretudo, a prevenção de ataques
de larga escala a sistemas através das vulnerabilidades descritos acima. Estes métodos podem
tornar a exploração dos buffers overflows, mas nenhum pode impedir todos os ataques.
2.8.1 Escrever código seguro
Os buffers overflows são resultado de se colocar mais código num buffer do que aquele que
este é suposto ter. As funções de C como strcpy, strcat, sprintf e vsprintf trabalham com
strings que terminam com null e não executam verificação dos limites. A função gets lê o
input do stdin (normalmente o teclado) até um carácter newline ou EOF (End Of File) for
9
UNIVERSIDADE ANHANGUERA-UNIDERP
encontrado.
Assim a melhor maneira de evitar buffers overflows é não permitir sequer que eles possam
ocorrer em primeiro lugar. Os programadores devem ser educadossobre como minimizarem o
uso de funções vulneráveis.
2.8.2 Invalidar a execução de código na pilha
Uma vez que o código malicioso é um input do programa, ele está na pilha e não na região de
código. Então, a solução mais simples é impedir que pudessem ser executadas instruções da
pilha. Qualquer código que tente executar outro código presente na pilha causaria uma
violação de segmento. No entanto esta solução não é fácil de executar.
2.8.3 Ferramentas do Compilador
Ao longo dos anos, os compiladores são cada vez mais agressivos nas otimizações e nas
verificações que efetuam. Vários compiladores avisam sobre o uso de funções pouco seguras
como o gets e o strcpy.
Por exemplo, o código:
int main () {
char *str = (char *)malloc(10);// aloca 10 bytes para str
gets (str); // lê do stdin e guarda em str
}
Quando compilado com o GCC devolve:
/tmp/cc203ViF.o: In function "main":
/tmp/cc203ViF.o(.text+0x1f): the "gets" function is dangerous and should not be used.
Além de darem avisos, os compiladores modernos alteram a maneira como um programa é
compilado, permitindo verificações de limites ir para o código compilado sem alterar a fonte.
Este tipo de ferramenta requer que o programa seja recompilado, o que pode ser complicado
se o programa não for open source. Entre essas ferramentas existe o Stackshield que copia o
endereço de retorno de uma função para um lugar seguro no início da função. Quando a
função termina, compara os endereços e aborta imediatamente a execução se estes forem
10
UNIVERSIDADE ANHANGUERA-UNIDERP
diferentes.
2.8.4 Verificações na altura da execução
Uma aplicação tem acesso restrito para prevenir ataques. Este método assenta na segurança do
código previamente carregado antes da aplicaçãoser executada. Este componente pré-
carregado pode fornecer versões mais seguras das funções perigosas, ou então garantir que os
endereços não são reescritos. Um exemplo é a livraria libsafe.
2.8.5 Runtime dinâmica
Evitar estouro de buffer através da implementação de um processo dinâmico de prevenção de
execução em seu sistema. Condições de estouro de buffer e os riscos são detectados durante a
execução do programa, neste método, impedindo um ataque de estouro de ocorrer. Processos
de execução diferentes incluem "canário" --- que adiciona a linha "canário" para a codificação
do seu programa e copia o endereço de retorno do programa. O último método serve como um
backup de informações como um meio de regenerar a funcionalidade do programa uma vez
que um ataque de estouro for resolvido.
RELATÓRIO 03 – UTILIZANDO CRIPTOGRAFIA
A seguir serão apresentados três métodos de criptografia: Base64, MD5 e SHA1. Logo após
serão apresentados exemplos desses métodos em cada linguagem. Ao final, os motivos pelos
quais os métodos MD5 e SHA1 são mais fortes que o Base64.
3.1 Base64 - Conceito
É um método para codificação de dados para transferência na internet. É utilizado
frequentemente para transmitir dados binários por meios de transmissão que lidam apenas
com texto, como por exemplo, para enviar arquivos anexos por e-mail.
Ela é uma codificação de mão dupla, e usando uma segunda função você pode descobrir a
string original de uma string codificada.
É constituído por 64 caracteres ([A-Za-z0-9], "/" e "+") que deram origem ao seu nome. O
carácter "=" é utilizado como um sufixo especial e a especificação original (RFC 989) definiu
11
UNIVERSIDADE ANHANGUERA-UNIDERP
que o símbolo "*" pode ser utilizado para delimitar dadosconvertidos, mas não criptografados,
dentro de um stream.
Esta codificação é amplamente utilizada por aplicações em conjunto com a linguagem de
marcação XML, possibilitando o armazenamento de dados binários em forma de texto.
3.2 MD5 - Conceito
O MD5 (Message-Digest-algorithm 5) é um algoritmo de hash de 128 bits unidirecional,
descrito na (RFC 1321), e muito utilizado por softwares com protocolo ponto-a-ponto (P2P,
ou Peer-to-Peer, em inglês) na verificação de integridade de arquivos e logins.
Uma hash md5 não pode ser transformada novamente no texto que lhe deu origem. O método
de verificação é, então, feito pela comparação das duas hash (uma da mensagem original
confiável e outra da mensagem recebida). O MD5 também é usado para verificar a integridade
de um arquivo através, por exemplo, do programa md5sum, que cria a hash de um arquivo.
Isto se pode tornar muito útil para downloads de arquivos grandes, para programas P2P que
constroem o arquivo através de pedaços e estão sujeitos a corrupção dos mesmos. Como
autenticação de login é utilizada em vários sistemas operacionais Unix e em muitos sites com
autenticação.
3.3 SHA1 - Conceito
A família de SHA (Secure Hash Algorithm) está relacionada com as funções criptográficas. A
função mais usada nesta família, a SHA-1, é usada numa grande variedade de aplicações e
protocolos de segurança, incluindo TLS, SSL, PGP, SSH, S/MIME e IPSec. SHA-1 foi
considerado o sucessor do MD5. Em algumas correntes, é sugerido que o SHA-256 ou
superior seja usado para tecnologia crítica. Os algoritmos SHA foram projetados
pela National Security Agency (NSA) e publicados como um padrão do governo Norte-
Americano.
Existem mais quatro variantes que foram lançadascom capacidades de saída aumentadas e um
design ligeiramente diferente: SHA-224, SHA-256, SHA-384, e SHA-512 — por vezes
chamadas de SHA-2.
3.4 Base64 – Na linguagem PHP
12
UNIVERSIDADE ANHANGUERA-UNIDERP
$string = 'O rato roeu a roupa do rei de Roma';
$codificada = base64_encode($string);
echo "Resultado da codificação usando base64: " . $codificada;
// TyByYXRvIHJldSBhIHJvcGEgZG8gcmVpIGRlIFJvbWE=
echo "
";
$original = base64_decode($codificada);
echo "Resultado da decodificação usando base64: " . $original;
// O rato roeu a roupa do rei de Roma
// Note que $original vai ser idêntica a $string
?>
3.5 MD5 – Na linguagem PHP
$string = 'O rato roeu a roupa do rei de Roma';
$codificada = md5($string);
echo "Resultado da codificação usando md5: " . $codificada;
// 54cf74d1acdb4037ab956c269b63c8ac
?>
3.6 SHA1 – Na Linguagem PHP
$string = 'O rato roeu a roupa do rei de Roma';
$codificada = sha1($string);
echo "Resultado da codificação usando sha1: " . $codificada;
// b186b709f7cf5a1d98d413379a66e511df8d59a4
?>
3.7 Base64 – Na Linguagem Java
13
UNIVERSIDADE ANHANGUERA-UNIDERP
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import java.io.IOException;
public class TesteBase64{
public static void main(String args[]){
BASE64Encoder encoder = new BASE64Encoder();
String code = encoder.encodeBuffer("Teste Base64".getBytes());
//Vai imprimir "Teste Base64 -(codificado)- VGVzdGUgQmFzZTY0"
System.out.println("Teste Base64 -(codificado)- " + code);
BASE64Decoder decoder = new BASE64Decoder();
try{
byte[] decoded = decoder.decodeBuffer("VGVzdGUgQmFzZTY0");
//Vai imprimir "VGVzdGUgQmFzZTY0 -(decodificado)- Teste Base64"
System.out.println("VGVzdGUgQmFzZTY0 -(decodificado)- " + newString(decoded));
}catch(IOException ex){
}
}
}
3.8 SHA1 – Na Linguagem Java
package main;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class HashTextTest {
public static void main(String[] args) throws NoSuchAlgorithmException {
14
UNIVERSIDADE ANHANGUERA-UNIDERP
System.out.println(sha1("test string to sha1"));
}
static String sha1(String input) throws NoSuchAlgorithmException {
MessageDigest mDigest = MessageDigest.getInstance("SHA1");
byte[] result = mDigest.digest(input.getBytes());
StringBuffer sb = new StringBuffer();
for (int i = 0; i < result.length; i++) {
sb.append(Integer.toString((result[i] & 0xff) + 0x100, 16).substring(1));
}
return sb.toString();
}
}
3.9 MD5 – Na Linguagem Java
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class CriptografiaMD5 {
private static MessageDigest md = null;
static {
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException ex) {
ex.printStackTrace();
}
}
private static char[] hexCodes(byte[] text) {
char[] hexOutput = new char[text.length * 2];
String hexString;
for (int i = 0; i < text.length; i++) {
hexString = "00" + Integer.toHexString(text[i]);
hexString.toUpperCase().getChars(hexString.length() - 2,
hexString.length(), hexOutput, i * 2);
}
15
UNIVERSIDADE ANHANGUERA-UNIDERP
return hexOutput;
}
public static String criptografar(String pwd) {
if (md != null) {
return new String(hexCodes(md.digest(pwd.getBytes())));
}
return null;
}
public static void main(String[] args){
String senha = "123456";
System.out.println(CriptografiaMD5.criptografar(senha));
senha = "132546";System.out.println(CriptografiaMD5.criptografar(senha));
}
}
3.10 Base64 – Na Linguagem ASP
O código abaixo esta cifrando o Nome Fabrizio Gianfratti e decifrando em ASP.
Imports System.Security.Cryptography
Imports System.IO
Imports System.Text
Public Class default2
Inherits System.Web.UI.Page
Private ChaveSecreta As String = "0987612345!@#$%¨&*"
Dim Texto As String = "Fabrizio Gianfratti"
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles MyBase.Load
Response.Write(Cifrar(Texto, ChaveSecreta) & "
")
16
UNIVERSIDADE ANHANGUERA-UNIDERP
Response.Write(Decifrar(Cifrar(Texto, ChaveSecreta), ChaveSecreta))
End Sub
Private Function Cifrar(ByVal vstrTextToBeEncrypted As String, ByVal vstrEncryptionKey
As String) As String
Dim bytValue() As Byte
Dim bytKey() As Byte
Dim bytEncoded() As Byte
Dim bytIV() As Byte = {121, 241, 10, 1, 132, 74, 11, 39, 255, 91, 45, 78, 14, 211, 22, 62}
Dim intLength As Integer
Dim intRemaining As Integer
Dim objMemoryStream As New MemoryStream
Dim objCryptoStream As CryptoStream
Dim objRijndaelManaged As RijndaelManaged
vstrTextToBeEncrypted = TiraCaracteresNulos(vstrTextToBeEncrypted)
bytValue = Encoding.ASCII.GetBytes(vstrTextToBeEncrypted.ToCharArray)
intLength = Len(vstrEncryptionKey)
If intLength >= 32 Then
vstrEncryptionKey = Strings.Left(vstrEncryptionKey, 32)
Else
intLength = Len(vstrEncryptionKey)
intRemaining = 32 - intLength
vstrEncryptionKey = vstrEncryptionKey & Strings.StrDup(intRemaining, "X")
End If
bytKey = Encoding.ASCII.GetBytes(vstrEncryptionKey.ToCharArray)
objRijndaelManaged = New RijndaelManaged
Try
objCryptoStream = New CryptoStream(objMemoryStream,
objRijndaelManaged.CreateEncryptor(bytKey, bytIV), CryptoStreamMode.Write)
17
UNIVERSIDADE ANHANGUERA-UNIDERP
objCryptoStream.Write(bytValue, 0,bytValue.Length)
objCryptoStream.FlushFinalBlock()
bytEncoded = objMemoryStream.ToArray
objMemoryStream.Close()
objCryptoStream.Close()
Catch
End Try
Return Convert.ToBase64String(bytEncoded)
End Function
Private Function Decifrar(ByVal vstrStringToBeDecrypted As String, ByVal
vstrDecryptionKey As String) As String
Dim bytDataToBeDecrypted() As Byte
Dim bytTemp() As Byte
Dim bytIV() As Byte = {121, 241, 10, 1, 132, 74, 11, 39, 255, 91, 45, 78, 14, 211, 22, 62}
Dim objRijndaelManaged As New RijndaelManaged
Dim objMemoryStream As MemoryStream
Dim objCryptoStream As CryptoStream
Dim bytDecryptionKey() As Byte
Dim intLength As Integer
Dim intRemaining As Integer
Dim intCtr As Integer
Dim strReturnString As String = String.Empty
Dim achrCharacterArray() As Char
Dim intIndex As Integer
bytDataToBeDecrypted = Convert.FromBase64String(vstrStringToBeDecrypted)
18
UNIVERSIDADE ANHANGUERA-UNIDERP
intLength = Len(vstrDecryptionKey)
If intLength >= 32 Then
vstrDecryptionKey = Strings.Left(vstrDecryptionKey, 32)
Else
intLength = Len(vstrDecryptionKey)
intRemaining = 32 - intLength
vstrDecryptionKey = vstrDecryptionKey & Strings.StrDup(intRemaining, "X")
End If
bytDecryptionKey = Encoding.ASCII.GetBytes(vstrDecryptionKey.ToCharArray)
ReDim bytTemp(bytDataToBeDecrypted.Length)
objMemoryStream = New MemoryStream(bytDataToBeDecrypted)
Try
objCryptoStream = New CryptoStream(objMemoryStream, _
objRijndaelManaged.CreateDecryptor(bytDecryptionKey, bytIV), _
CryptoStreamMode.Read)
objCryptoStream.Read(bytTemp, 0, bytTemp.Length)
objCryptoStream.FlushFinalBlock()
objMemoryStream.Close()
objCryptoStream.Close()
Catch
End Try
Return TiraCaracteresNulos(Encoding.ASCII.GetString(bytTemp))
19
UNIVERSIDADE ANHANGUERA-UNIDERP
End Function
Private FunctionTiraCaracteresNulos(ByVal vstrStringWithNulls As String) As String
Dim intPosition As Integer
Dim strStringWithOutNulls As String
intPosition = 1
strStringWithOutNulls = vstrStringWithNulls
Do While intPosition > 0
intPosition = InStr(intPosition, vstrStringWithNulls, vbNullChar)
If intPosition > 0 Then
strStringWithOutNulls = Left$(strStringWithOutNulls, intPosition - 1) & _
Right$(strStringWithOutNulls, Len(strStringWithOutNulls) - intPosition)
End If
If intPosition > strStringWithOutNulls.Length Then
Exit Do
End If
Loop
Return strStringWithOutNulls
End Function
End Class
3.11 MD5 – Na Linguagem ASP
private string GetMD5HashData(string data)
{
var md5 = MD5.Create();
byte[] hashData = md5.ComputeHash(Encoding.Default.GetBytes(data));
var returnValue = new StringBuilder();
20
UNIVERSIDADE ANHANGUERA-UNIDERP
for (int i = 0; i < hashData.Length; i++)
{
returnValue.Append(hashData[i].ToString());
}
return returnValue.ToString();
}
private bool ValidateMD5HashData(string inputData, string storedHashData)
{
string getHashInputData = GetMD5HashData(inputData);
if (string.Compare(getHashInputData, storedHashData) == 0)
{
return true;
}
else
{
return false;
}
}
3.12 SHA1 – Na Linguagem ASP
private string GetSHA1HashData(string data)
{
SHA1 sha1 = SHA1.Create();
byte[] hashData = sha1.ComputeHash(Encoding.Default.GetBytes(data));
StringBuilder returnValue = new StringBuilder();
for (int i = 0; i < hashData.Length; i++)
{
returnValue.Append(hashData[i].ToString());
}
return returnValue.ToString();
}
21
UNIVERSIDADE ANHANGUERA-UNIDERP
private bool ValidateSHA1HashData(string inputData, string storedHashData)
{
string getHashInputData = GetSHA1HashData(inputData);
if (string.Compare(getHashInputData, storedHashData) == 0)
{
return true;
}
else
{
returnfalse;
}
}
3.12 Conclusão – Comparação entre os métodos
Conforme pesquisa realizada, SHA1 e MD5 são mais fortes que o Base64, porque são
unidirecionais não sendo possível decodificar os mesmos. O código Base64 é utilizado apenas
para mensagem da internet e ele converte a string/binário de entrada em um dado codificado
com MIME base64, que pode ser facilmente decodificado pelo comando inverso,
base64_decode.
22
UNIVERSIDADE ANHANGUERA-UNIDERP
BIBLIOGRAFIA
BRAZ, F. Instrumentação da analise e projeto de software seguro baseada em ameaças e
padrões. Tese (Doutorado em Engenharia Elétrica) – Faculdade de Tecnologia, Brasília, 2009.
CRUZ, Edimar Fernando, et al. “TSDD - Teste de segurança durante o desenvolvimento”,
União Educacional Minas Gerais – Uniminas – Uberlândia, MG – Brasil – Artigo para
Especialização em Segurança da Informação, 2007.
MCAFEE. Cybercrime cost $1 trillion last year, study. 2009. Disponível em: <
http://www.zdnet.com/article/cybercrime-cost-1-trillion-last-year-study/ >. Acesso em 15
mar. 2015.
WAGNER, Rosana. Processo de desenvolvimento de software confiável baseados em padrões
de segurança. Tese (Mestre em Informática) – UFSM Universidade de Federal de Santa Maria
UFSM, Santa Maria-Rio Grande do Sul, 2011.
DEVMEDIA. Criptografia de dados 128 bits. Disponível em: <
http://www.devmedia.com.br/criptografia-de-dados-128-bits/3112 >. Acesso em 21 mar.
2015.
EMILIO2HD. Usando base64 no Java. 2010. Disponível em: < http://emilio2hd.com.br/
usando-base64-no-java/ >. Acesso em 20 mar. 2015.
GRIS. Buffer overflow – Uma introdução Teórica. 2008. Disponível em: . Acesso em 18 mar.
2015.
INTOWEB.Criptografia com Sha-1 ou Base64. 2008. Disponível em: <
http://intoweb.blogspot.com.br/2008/09/criptografia-com-sha-1-ou-base64.html >. Acesso em
20 mar. 2015.
LAFAPRO. O ataque por buffer overflow. 2005. Disponível em: <
23
UNIVERSIDADE ANHANGUERA-UNIDERP
http://www.lafa.pro.br/pe/artigos/buffer_overflow-criandovirus.pdf >. Acesso em 20 mar.
2015.
SHA1 ONLINE. SHA1 Java. Disponível em: < http://www.sha1-online.com/sha1-java/ >.
Acesso em 20 mar. 2015.
VESTCON. Princípios básicos da segurança da informação. 2011. Disponível em: . Acesso
em 15 mar. 2015.
VIRTUAL BASE. Como criar uma chave simples usando MD5 e SHA1. 2014. Disponível
em: < http://blog.virtualbase.com.br/2014/03/Criptografia2.html#.VQ21bo7F_Mo >. Acesso
em 21 mar. 2015.
VIVA O LINUX. Princípios da segurança da informação. 2004. Disponível em: . Acesso em
15 mar. 2015.
WIKIPEDIA. Return-to-libc attack. 2012. Disponível em: . Acesso em 15 mar. 2015.
WIKIPEDIA. Off-by-one error. 2014. Disponível em: . Acesso em 18 mar. 2015.
WIKIPEDIA. Heap overflow. 2012. Disponível em: . Acesso em 18 mar. 2015.
WIKIPEDIA. Base64. 2012. Disponível em: < http://pt.wikipedia.org/wiki/Base64 >. Acesso
em 20 mar. 2015.
WIKIPEDIA. MD5. 2012. Disponível em: < http://pt.wikipedia.org/wiki/MD5 >. Acesso em
20 mar. 2015.
WIKIPEDIA. SHA1. 2012. Disponível em: < http://pt.wikipedia.org/wiki/SHA1 >. Acesso
em 20 mar. 2015.
24