Algoritmo de criptografia para a passagem de notas entre professores e
pró-reitoria de graduação
Raphael Constant da Costa
Instituto Tecnológico de Aeronáutica - ITA/CTA 12228-900 – São José dos Campos, São Paulo, Brasil Bolsista PIBIC-CNPq.
Endereço eletrônico: [email protected]
Tania Nunes Rabello
Instituto Tecnológico de Aeronáutica - ITA/CTA 12228-900 – São José dos Campos, São Paulo, Brasil Endereço eletrônico: [email protected]
Resumo O artigo busca mostrar o desenvolvimento de um projeto baseado em conceitos de criptografia, mais especificamente no
uso de funções hash. Trata-se de um algoritmo misto, visto que utiliza conceitos de criptografia simétrica e assimétrica. O criptosistema de chave simétrica utilizado foi o DES, o de chave assimétrica RSA e, por último, a função hash utilizada foi a SHA-1. O objetivo é facilitar a troca de notas entre professores, coordenadores e pró-reitoria de graduação, fazendo com que a mesma possa ocorrer via internet.
Palavras chave: criptografia, RSA, DES, SHA-1. 1. Introdução
Num mundo em que há uma circulação de informações cada vez maior, muitas vezes torna-se inviável a presença física para, por exemplo, se assinar um documento. O avanço da Internet vem possibilitando que um número cada vez maior de transações sejam feitas através da mesma. A criptografia é uma ciência onde se estuda a confiabilidade dessas trocas de informações, descobrindo métodos de transformar mensagens ou assinaturas em algo que impossibilitaria que um intruso tivesse acesso ou forjasse as mesmas. Porém, muitas vezes um documento a ser assinado possui um tamanho muito grande, tornando a assinatura quase impraticável. As funções hash, assunto do presente trabalho, servem para transformar um processo de assinatura em algo de tamanho menor e fixo (um resumo).
Este trabalho mostrará uma implementação, usando também funções hash, de um algoritmo misto. Misto se deve ao fato de também ser utilizado um algoritmo de chave simétrica, o DES, e um algoritmo de chave assimétrica, o RSA. O principal objetivo da criptografia é possibilitar que duas pessoas se comuniquem por um canal, muitas vezes inseguro, de tal forma que um terceiro não possa entender o que está sendo dito. O processo de criptografar e decriptografar é feito através de chaves.
A criptografia se divide em dois tipos principais: simétrica e assimétrica.
Na criptografia simétrica, emissor e receptor possuem a mesma chave. Esse tipo de criptografia possibilita o uso de funções matemáticas mais simples e por isso é mais rápida, porém é necessário que a troca da chave comum seja realizada por um canal seguro, pois uma vez que um intruso tenha o conhecimento da chave ele pode usá-la para decriptografar qualquer mensagem. Se para cada par de usuários que trocam informações pela Internet fosse necessária a troca de chaves por um canal seguro, teríamos algo impraticável.
A criptografia assimétrica surge para suprir a deficiência acima citada. Ela corrige o problema de distribuição de chaves, pois na mesma não é necessário que emissor e receptor possuam a mesma chave: existe uma chave para criptografar e outra chave para decriptografar. A chave que faria a mensagem ser criptografada seria uma chave pública e a chave usada para decriptografar a mensagem seria uma chave privada. A chave pública é publicada em um diretório de maneira que qualquer pessoa tenha acesso à mesma. A chave privada é conhecida somente pela pessoa que recebe a mensagem, de tal forma que somente ela possa decriptografar mensagens recebidas.
Caso um intruso tenha acesso a uma mensagem criptografada, o mesmo poderia com a chave pública do destinatário, criptografar várias mensagens até encontrar a mensagem que, criptografada, forneceria a mensagem critptografada interceptada, logo ele teria conhecimento da mensagem original. Por esse motivo, a criptografia assimétrica envolve funções matemáticas mais complexas (mais difícil para o computador realizar), tornando o processo de criptografar e decriptografar mais lento.
É válido salientar que algoritmos utilizados tanto na criptografia simétrica quanto na criptografia assimétrica são de conhecimento público, o que não fornece insegurança visto que a segurança do processo criptográfico está no não conhecimento da chave, e não no não conhecimento do algoritmo.
2. The data encryption standard (DES)
É o algoritmo de chave simétrica mais utilizado do mundo. DES criptografa uma seqüência de bits de tamanho 64(a mensagem) usando uma chave K. Esta chave consiste de uma seqüência de bits de tamanho 56. É então obtido um texto cifrado, que também consiste de uma seqüência de bits de comprimento 64. O algoritmo consta de três estágios: 1º Dado uma mensagem x, uma seqüência de bits é construída ao se permutar os bits de x de acordo com uma (fixa) permutação inicial IP. Escrevemos
0
x
( )
0 0 0IP
x
L
R
x
=
=
, onde consiste dos primeiros 32 bits de IP(x) e consiste dos 32 últimos.0
L R0
2º Dezesseis iterações de uma certa função são calculadas. Nós calculamos LiRi, 1≤ i≤16, de acordo com a seguinte regra: 1 − = i i R L ) , ( 1 1 i i i i L f R K R = − ⊕ −
onde denota a operação ou-exclusivo entre duas seqüência de bits. A função f será descrita posteriormente. são seqüências de bits de tamanho 48 geradas a partir da chave K. Um passo da encriptação é descrito na figura 1 [2] abaixo: ⊕ 16 2 1,K ,...,K K
Figura 1. Um passo da encriptação do DES
3º Aplica-se a permutação inversa IP−1 à seqüência de bits , obtendo o texto cifrado y, isto é, . Notemos a ordem invertida de e . Tal ordem invertida é fundamental para que no processo de decriptação possamos obter a mensagem original x.
16 16L R ) ( 16 16 1 R L IP y= − L16 R16
A função f toma como argumento A, que é uma seqüência de bits de tamanho 32, e como segundo argumento J que é uma seqüência de bits de tamanho 48, e produz como saída uma seqüência de bits de tamanho 32. Os seguintes passos são executados:
1º O primeiro argumento A é “expandido“ a uma seqüência de bits de tamanho 48 de acordo com uma função expansão E. E(A) consiste de 32 bits de A, permutados de uma certa maneira, com 16 desses 32 bits aparecendo duas vezes. 2º Calcula-se E(A)⊕J e escreve-se o resultado como concatenação de 8 sequências de 6 bits cada,
. 8 7 6 5 4 3 2 1B B B B B B B B B=
3º Esse próximo passo usa 8 caixas S, designadas por . Cada é uma matriz , com elementos sendo inteiros variando de 0 à 15. Dado uma seqüência de bits de tamanho seis, digamos , calcula-se
como segue. Os dois bits determinam a representação binária de uma linha c de
8 1,..., S S Si 4×16 6 5 4 3 2 1b b b b b b Bj = ) ( j j B S
b
1b
6S
j(
0
≤ c
≤
3
)
e osbits b2b3b4b5 determinam a representação binária de uma coluna r de Sj
(
0
≤ r
≤
15
)
. Então é definida como sendo o elemento da c--ésima linha e r-ésima coluna da matriz S) ( j j B S
j escrita em binário como uma seqüência de bits de tamanho 4. Desta maneira, calculamos Cj =Sj(Bj),1≤ j≤8.
4º A seqüência de bits é permutada de acordo com uma permutação fixa P. A seqüência de bits resultante é definida como sendo A função f é descrita na figura 2 [2] abaixo:
8 7 6 5 4 3 2 1C C C C C C C C C= ) (C P f(A,J).
Figura 2. A função f do DES
3. O algoritmo de Rivest, Shamir e Adleman (RSA)
É um dos algoritmos de chave pública mais famosos e utilizados do mundo. Seu algoritmo é baseado na dificuldade de se fatorar inteiros muito grandes. Para se construir o algoritmo, antes é necessário a função de Euler e o conhecimento do teorema de Euler.
Φ
Definição 4 Se n é um inteiro positivo, a função Φ de Euler, denotada por Φ(n), é definida como sendo o número de inteiros positivos menores ou iguais a n que são relativamente primos com n, isto é, o máximo divisor comum de n e tais números vale 1.
Teorema 5 (Euler) Se m é um inteiro positivo e a um inteiro tal que máximo divisor comum entre a e m vale 1((a,m)=1), então ) (mod 1 ) (m m aΦ ≡ ,
ou seja, o resto da divisão de entre aΦ(m) e m vale 1.
A demonstração não será apresentado por ser muito parecida com a demonstração do teorema de Fermat, já mostrada no relatório parcial.
Suponhamos que em nosso esquema, um usuário A deseja mandar uma mensagem para um usuário B. Temos então.
● Geração das chaves pública e privada de B: 1. São gerados dois primos grandes p e q.
2. Calcula-se n= pqe Φ(n)=(p−1)(q−1).
3. Escolhe-se um inteiro e tal que (Φ(n),e)=1 e 1<e<Φ(n).
4. Usando o algoritmo estendido de Euclides calcula-se o único inteiro d tal que de≡1(modΦ(n)). A chave pública de B é dada pelo par (e,n) e a chave privada de B é dada pelo valor d. ● Encriptação da mensagem:
1. A deve obter a chave pública de B
2. A mensagem deve ser representada como um inteiro x entre 0 e n-1.
3. Calcula-se o valor criptografado da mensagem c=xemodn, isto é, o resto da divisão de xe por n. 4. Envia-se o texto cifrado c para B.
● Decriptação da mensagem:
1. B deve usar a chave privada d e calcular x=cdmodn.
Para o algoritmo funcionar, deve então ser verdade que . Isto é verdade, pois: Como x é um inteiro entre 0 e n-1, pelo teorema fundamental da aritmética, x pode ser representado como segue:
n d c x= mod k a k p a p a p x= 1 1 2 2... ,
onde pi,i=1,2,...,k são números primos e ai,i=1,2,...,k são números inteiros positivos. Como de≡1(modΦ(n)), temos , para algum inteiro . Como os são primosmenores do que n, temos
e pelo teorema de Euler: 1 ) ( + Φ =t n de t≥1
p
i´
s
k i n i p , ) 1, 1,2,..., ( = = ) (mod ) ) ) ( ...( 1 ) ) ( 1 (( ) ) ( ( 1 ) ( ) (xe d xt n x n tx p n a pk n ak tx n d c ≡ ≡ Φ + ≡ Φ ≡ Φ Φ ) (mod ) 1 ... 2 1 1 1 ( a a ak tx≡x n ≡ .Notemos então o motivo de somente B poder possuir o valor d. Uma vez encontrado esse valor, um oponente poderia decriptografar qualquer mensagem. Notamos também que os valores de p e q devem ser privados, isto é, somente B pode conhecê-los. Esses valores devem ser grandes o suficiente de maneira que dado o valor n, que é público, deve ser computacionalmente inviável calcular seus fatores primos p e q, pois uma vez calculado esses valores um oponente calcularia facilmente Φ(n)=(p−1)(q−1) e através do valor público e, calcularia seu inverso módulo
, obtendo assim o valor d. )
(n Φ
4. Funções hash
Quanto maior a mensagem a ser criptografada, maior quantidade de informação precisará ser processada e conseqüentemente o processo de criptografar a mensagem torna-se mais lento. Isso é ainda mais perceptível na criptografia assimétrica, onde as funções matemáticas usadas para criptografar são mais complexas. Uma solução para criptografar mensagens mais longas são as funções hash, que transformam uma mensagem de tamanho arbitrário num resumo da mensagem de tamanho especificado. Qualquer operação desejada é realizada com o resumo.
Exigências para uma função hash
As funções hash devem satisfazer algumas condições para não enfraquecer a segurança dos algoritmos de criptografia no qual elas são usadas. Será necessário então que uma função hash h satisfaça algumas propriedades para prevenir falsificações:
1. Se x é uma mensagem, deve ser computacionalmente inviável encontrar uma mensagem x´≠xtal que h(x´) = h(x). 2. Deve ser computacionalmente inviável encontrar duas mensagens x e x´ tais que x´≠x e h(x´) = h(x).
3. Dado um resumo z, deve ser computacionalmente inviável encontrar uma mensagem x tal que h(x) = z.
Existem diversas funções hash, algumas atualmente não são mais seguras (não satisfazem mais as três propriedades acima), como a função hash MD4, até algumas atualmente ainda seguras, como SHA-1, que é utilizada no atual projeto e por isso escolhida para ser detalhada a seguir. Devemos salientar que funções hash que satisfazem as três propriedades acima citadas podem não mais satisfazer tais propriedades no futuro, pois possíveis ataques podem ser descobertos, sendo necessária melhorias no algoritmo ou até mesmo um algoritmo totalmente novo.
sh algorithm (SHA-1)
SHA-1 é uma versão melhorada da função hash SHA, que por sua vez é baseada no MD4. Lógi
o saída um resumo de locos de tamanho de 512 bits.
processamento consiste dos seguintes passos:
consiste da adição de um bit com valor 1 seguido pelo número ecessário de bits que faltam assumindo o valor 0.
s sem sinal (bit mais significativo primeiro) e contém o comprimento da mensagem original (antes o preenchimento)
o registros (A, B, C, D, E). Estes registros são inicializados pelos seguintes inteiros de 32 bits (valores hexadecimais):
E = C3D2E1F0
ais à esquerda. Como strings de 32 bits, os valores de inicialização (em hexadecimal) aparecem como segue:
Palavra E = C3 D2 E1 F0 4.1 The secure ha
ca do SHA-1
O algoritmo tem como entrada uma mensagem de tamanho máximo 264 bits e produz com tamanho 160 bits. A entrada é processada em L b
O
● Passo 1: Preenchimento de bits faltantes: A mensagem é preenchida de tal forma que seu comprimento seja congruente a 448 módulo 512, ou seja, o resto do comprimento da mensagem quando dividido por 512 seja 448. O preenchimento é sempre feito, mesmo que a mensagem já se encontre na forma desejada. Daí, o número de bits a serem preenchidos varia de 1 a 512. O preenchimento
n
● Passo 2: Anexando o comprimento da mensagem: Um bloco de 64 bits é anexado à mensagem. O bloco consta de um inteiro de 64 bit
d
● Passo 3: Inicialização do registro: Um buffer de 160 bits é usado para guardar valores intermediários e finais da função hash. O buffer pode ser representado por cinc
A = 67452301 B = EFCDAB89
C = 98BADCFE D = 10325476
Estes valores são armazenados no formato big-endian, onde o bit mais significativo está na posição m
Palavra A = 67 45 23 01 Palavra B = EF CD AB 89
Palavra C = 98 BA DC FE Palavra D = 10 32 54 76
● Passo 4: Processamento da mensagem em bloco de 512 bits(16 palavras): O coração do algoritmo é um módulo que consiste de quatro rounds de processamento com 20 passos cada. A lógica é mostrada na figura 3 [1]. Os quatros rounds possuem uma estrutura similar, mas cada um usa uma função lógica primitiva diferente, que nos referiremos como f1,f2,f3 e f4.
Figura 3. Processamento do SHA-1 de um bloco de 512 bits
Cada round tem como entrada o bloco de 512 bits atual que está sendo processado e o valor do buffer de 160 bits ABCDE e atualiza o conteúdo do buffer. Cada round também faz uso de uma constante aditiva , onde
éum dos 80 passos através dos 4 rounds. De fato, apenas quatro constantes aditivas são usadas. Os valores, em hexadecimal e decimal, são dados na tabela a seguir:
) ( qY t K 79 0≤ t≤
Tabela 1. Valores das constantes usadas no SHA-1
Número do Passo Hexadecimal Parte inteira de
19 0≤ t≤ Kt =5A827999 ⎥⎦ ⎤ ⎢⎣ ⎡230× 2 39 20≤ t≤ Kt =6ED9EBA1 ⎥⎦ ⎤ ⎢⎣ ⎡230× 3 59 40≤ t≤ Kt =8F1BBCDC ⎥⎦ ⎤ ⎢⎣ ⎡230× 5 79 60≤ t≤ Kt =CA62 DC1 6 ⎥⎦ ⎤ ⎢⎣ ⎡230× 10
A saída do quarto round (octogésimo passo) é adicionada à entrada do primeiro round para produzir . A adição é feita independentemente para cada uma das cinco palavras no buffer com cada uma das correspondente palavras em , usando adição módulo
) (CVq ) 1 (CVq+ q CV 232.
● Passo 5: Saída Após todos os L blocos de 512 bits terem sido processados, a saída do L-ésimo estágio é o valor hash da mensagem.
Podemos resumir o algoritmo SHA-1 como segue: CV0=IV
CVq+1=SUM32(CVq,ABCDEq)
MD=CVL onde
=
IV Valor inicial do buffer ABCDE, definido no passo 3 q
ABCDE = A saída do último round do processamento do q-ésimo bloco da mensagem
L = O número de blocos na mensagem (incluindo bits preenchidos e o campo com o comprimento da mensagem original)
32
SUM = Adição módulo
2
32 realizada separadamente em cada palavra do par de entrada MD = valor final do resumo da mensagemA Função Compressora do SHA-1
Vamos olhar em mais detalhes a lógica de cada um dos 80 rounds do processamento de um bloco de 512 bits. Cada round é da forma:
A,B,C,D,E
←
( E + f(t,B,C,D) + S5(A) + Wt + Kt ,A,S30(B),C,D ) OndeA, B, C, D, E = As cinco palavras do buffer T = Número do passo;0≤ t≤79
f(t, B, C, D) = função lógica primitiva para o passo t
S = rotação à esquerda de k bits de um argumento de 32 bits k t
W = Uma palavra de 32 bits derivada da entrada atual de 512 bits t
K = uma constante aditiva; quatro valores distintos são usados, como definido previamente + = adição módulo
2
32Cada função primitiva tem como entrada três palavras de 32 bits e saída uma palavra de 32 bits. Cada função executa um conjunto de operações bit a bit; isto é, o n-ésimo bit da saída é função do n-ésimo bit das três entradas. As funções são dadas como segue na tabela abaixo:
Tabela 2. Designação das funções primitivas
Passo Função Valor da unção
) 19 0 ( ≤ t≤ f1= f(t,B,C,D) (B∧C)∨(B∧D) ) 39 20 ( ≤ t≤ f2= f(t,B,C,D) B⊕C⊕D ) 59 40 ( ≤ t≤ f3= f(t,B,C,D) (B∧C)∨(B∧D)∨(C∧D) ) 79 60 ( ≤ t≤ f4= f(t,B,C,D) B⊕C⊕D
As operações lógicas (e, ou, não, ou-exclusivo) são representadas pelos símbolos (∧,∨, ,⊕). A tabela-verdade destas funções é dada na tabela a seguir:
Tabela 3. Tabela-verdade das funções lógicas B C D 19f0.. f20..39 f40..59 f60..79 0 0 0 0 0 0 0 0 0 1 1 1 0 1 0 1 0 0 1 0 1 0 1 1 1 0 1 0 1 0 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 0 1 0 1 1 1 1 1 1 1 Por último, temos como as palavras de 32 bits são derivadas do bloco de 512 bits. Os primeiros 16 valores de são tomados diretamente das 16 palavras do bloco que está sendo processado. Os valores restantes são definidos como segue: t W t W ) ( 16 14 8 3 1 − − − − ⊕ ⊕ ⊕ = t t t t t S W W W W W
Daí, para os 64 passos restantes, o valor de consiste de uma rotação de 1 bit à esquerda do valor ou-exclusivo dos quatro valores precedentes de
t W . t W 5. Desenvolvimento do projeto
Atualmente, a passagem de notas do professor à Pró-Reitoria de Graduação ainda é feita sem o auxílio da Internet. Um exemplo disto é a necessidade de um disquete com as notas preenchidas pelo professor e um documento com a assinatura do professor. A idéia é que tais notas possam ser passadas via Internet e que de alguma forma possamos garantir que tais notas que chegam à Pró-Reitoria de Graduação são as mesmas que aquelas que o professor enviou, ainda mais, que qualquer interceptação feita durante o processo de envio e uma possível mudança nessas notas possam ser detectadas na Pró-Reitoria de Graduação, existindo uma assinatura digital. Teríamos então o seguinte esquema: 1º Professor preenche as notas em uma planilha do Excel e as envia ao coordenador do curso.
2º O coordenador verifica se não há problema com as notas, e as envia para a Pró-Reitoria de Graduação dando o consentimento da validade das notas.
3º A Pró-Reitoria de Graduação recebe as notas, reconhece que são as mesmas mandadas pelo professor e que as mesmas são válidas.
Com base nas nossas necessidades, temos o seguinte algoritmo e a explicação do funcionamento: Algoritmo desenvolvido : P C P → C E K
[
ID
p||M
||EU
PR[
ER
P[
ID
p||H M
( )]]]
: C P R C → P R E K[
ID
p||M
||EU
PR[
ER
P[
ID
p||H M
( )]]]
Onde: P = professor C = coordenador de curso PR = pró-reitoria de graduação M = planilha com notasE = função encriptadora usando a chave que vem em seguida PC
K = chave simétrica compartilhada pelo professor e coordenador de curso CPR
K = chave simétrica compartilhada pelo coordenador de curso e pró-reitoria
= p
ID identificador do professor
) (M
H = resumo da planilha de notas após aplicada a função hash || = concatenação
PR
P
R = chave privada do professor
com o coordenador, decriptografa ois
grafar o resumo da planilha de notas, de tamanho fixo, e otas, que pode ser um documento grande.
ário ione independente do computador dos professores, coordenadores e pró-reitoria de graduação.
r ele er possibilitado a execução deste trabalho juntamente com o curso
este trabalho, pelo acompanhamento, dedicação, atenção e
odrigo Cunha de Paiva por se dispor a tirar dúvidas a respeito de criptografia de linguagem Java. O professor compartilha uma chave com o coordenador do curso, num esquema de chave simétrica, aqui o DES será usado. O professor toma sua chave privada (RSA será usado) e com a mesma criptografa a planilha de notas concatenada com seu identificador. O mesmo pega este último resultado e agora criptografa com a chave pública da pró-reitoria de graduação. O prodessor finalmente pega este último resultado, concatena com a planilha de notas e com seu identificador, criptografando tudo com a chave simétrica compartilhada com o coordenador e enviando para o mesmo, conforme o esquema ilustrado. O coordenador usando a mesma chave simétrica decriptografa o que recebeu, podendo conferir o identificador do professor e também observar as notas. Ao dar seu parecer favorável, o coordenador então toma a chave simétrica que o mesmo compartilha com a pró-reitoria (o DES novamente é usado) e envia para a mesma. A pró-reitoria, usando a mesma chave simétrica compartilhada o que recebeu, podendo utilizar sua chave privada para decriptografar o valor
EU
PR[
ER
P[
ID
p||H M
( )]]
, dep utiliza a chave pública do professor para obter a planilha de notas juntamente com o identificador do professor.A pró-reitoria de graduação pode então aplicar a função hash na planilha de notas recebida e comparar com o valor hash da planilha de notas recebido, qualquer alteração na planilha de notas causará valores da função hash diferentes, indicando tentativa de fraude. A pró-reitoria de graduação sabe que o resumo da planilha de notas é válido devido ao fato de coordenador ter mandado o mesmo (portanto o coordenador deu as notas como válida) e também ao fato, ao obter as notas e o identificador depois do processo de decriptação, de somente o professor possuir a chave privada e portanto somente ele poderia fazer com que a pró-reitoria recebesse o identificador e as notas. Devido a esta última observação, salienta-se também que o algoritmo não necessita da confiança do coordenador de curso, visto que para ele (ou um intruso qualquer) tentar alterar as notas, seria necessário a inclusão do valor hash da falsa planilha de notas, o que é impossível devido ao fato de somente o professor possuir a chave privada. Não se tem problema ao utilizar criptografia assimétrica, pois a utilizamos apenas para cripto
não a planilha de n 6. Conclusões
Foram estudados conceitos de criptografia, possibilitando a criação de um algoritmo seguro que terá uma finalidade prática para enviar as notas com segurança dos professores até a pró-reitoria de graduação.
Depreende-se, do algoritmo descrito, quea segurança do algoritmo não depende da boa índole do coordenador do curso: qualquer mudança nas notas feitas por esse ou até mesmo um terceiro seria detectada, pois a pró-reitoria recebe tanto uma mensagem como o resumo da mensagem original, o que possibilita a detecção de qualquer modificação nas notas através de uma comparação.
Salientamos também que se o criptosistema de chave pública fosse aplicado diretamente à mensagem, possivelmente teríamos um algoritmo muito lento. Este problema passa a ser contornado com a função hash, pois temos que o criptosistema de chave pública criptografa o resumo da mensagem concatenado com o identificador, o que é bem menor.
A linguagem Java foi escolhida para a implementação do projeto, pois tem a vantagem de possuir classes prontas que já contêm algoritmos de criptografia, incluindo os utilizados no mesmo. Ela também pode executar seus programas sem uma plataforma fixa, em outras palavras, ela se ajusta a algumas características que o computador de cada usuário possui, o que é altamente necessário no atual projeto, visto que teremos troca de informações via Internet e é necess que o programa func
7. Agradecimentos
Primeiramente sempre a Deus, em especial po t ●
do ITA, que nos possibilita pouco tempo livre.
● Ao CNPq, por ter dado suporte financeiro a este trabalho. ● À professora Tania Nunes Rabello, orientadora d compreensão mostrados durante a execução do mesmo.
● Ao aluno Rafael Fernandes Cunha, por toda a atenção dada a eventuais dúvidas. ● Ao ex-aluno R
ntice Hall – 2o ed. ] Stinson , Douglas R., 2002, “Cryptography: theory and practice” – CRC Press, 2º ed., N.Y.
[1] Stallings, W.,1998, “Cryptography and Network Security: Principles and Practice” - Ed. Pre [2