ATPS Desenvolvimento de Sotware Seguro

35
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 1

description

ATPS Desenvolvimento de sotware seguro

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

UNIVERSIDADE ANHANGUERA-UNIDERP25