Sie sind auf Seite 1von 86

UNIVERSIDADE FEDERAL FLUMINENSE

SIDNEY LOYOLA DE S

ASSINATURA DE DOCUMENTOS ELETRNICOS


UTILIZANDO ANDROID

Niteri
2012

SIDNEY LOYOLA DE S

ASSINATURA DE DOCUMENTOS ELETRNICOS


UTILIZANDO ANDROID

Trabalho de Concluso de Curso submetido ao Curso de Tecnologia em Sistemas de Computao da Universidade


Federal Fluminense como requisito parcial para obteno do ttulo de Tecnlogo em Sistemas de Computao.

Orientador:
Jacques Alves da Silva

NITERI
2012

SIDNEY LOYOLA DE S

ASSINATURA DE DOCUMENTOS ELETRNICOS


UTILIZANDO ANDROID
Trabalho de Concluso de Curso submetido ao Curso de Tecnologia em Sistemas de Computao da Universidade
Federal Fluminense como requisito parcial para obteno do ttulo de Tecnlogo em Sistemas de Computao.

Niteri, ___ de _______________ de 2012.


Banca Examinadora :
_________________________________________
Prof. Jacques Alves da Silva, Dsc. Orientador
UFF Universidade Federal Fluminense

_________________________________________
Prof. Eyder Franco Sousa Rios, Msc. Avaliador
UFF Universidade Federal Fluminense

Dedico este trabalho a minha me que sonhou com esse dia e essa realizao. Conseguimos.

AGRADECIMENTOS

A minha esposa que permaneceu paciente,


carinhosa e compreensiva durante toda essa
jornada.

A meu Orientador Jacques da Silva pela


ateno que me concedeu durante esse trabalho.

Aos Colegas de curso pelo incentivo e troca


de experincias.

Ao CEDERJ por me proporcionar um curso


de excelente qualidade.

A mquina pode fazer a tarefa de 50 homens comuns. Mquina nenhuma capaz


de fazer o trabalho de um homem extraordinrio. Elbert Hubbard

RESUMO

Atualmente o poder computacional dos dispositivos mveis permite aplicaes sofisticadas e complexas, assim j possvel utiliza-los para aplicaes criptogrficas. O
objetivo deste trabalho desenvolver um aplicativo para Android que permita a realizao de assinaturas digitais, bem como um estudo sobre criptografia e sobre as
tcnicas criptogrficas necessrias para a realizao da Assinatura Digital. O Android foi escolhido por ser uma plataforma livre e de cdigo aberto, ideal para o
aprendizado e para a pesquisa. No final do trabalho apresentamos nossas concluses e sugestes para trabalhos futuros.
Palavras-chaves: Android, Criptografia e Assinatura Digital.

ABSTRACT

Currently the computational power of mobile devices allows sophisticated and complex applications, so it is possible to use them for cryptographic applications. The
objective of this work is to develop an application for Android that allows digital signatures and a study on encryption and cryptographic techniques necessary for the Digital Signature. The Android was chosen because it is a free platform and open source,
ideal for learning and research. At the end of the paper we present our conclusions
and suggestions for future work.

Key words: Android, Encryption and Digital Signature.

LISTA DE ILUSTRAES

Figura 1: Esquema de Criptografia Simtrica ............................................................ 18


Figura 2: Esquema de Criptografia Assimtrica ........................................................ 25
Figura 3 : Viso Alto Nvel da Pilha de Software Android [5] ..................................... 34
Figura 4 : Tela de configurao AVD ........................................................................ 37
Figura 5 : Viso da Estrutura de um Projeto Android ................................................ 39
Figura 6: Diagrama Casos de Uso ............................................................................ 42
Figura 7 : Diagrama de Atividades do Processo de Assinatura................................. 44
Figura 8 : Diagrama de Atividades do Processo de Verificao de Assinatura ......... 46
Figura 9 : Diagrama de Sequncia do Processo de Assinatura ................................ 47
Figura 10 : Diagrama de Sequncia do Processo de verificao da Assinatura ....... 48
Figura 11 : Telas do Aplicativo Desenvolvido ............................................................ 49

LISTA DE TABELAS

Tabela 1: Exemplo de Cifra utilizando Chave............................................................ 20


Tabela 2: Exemplo de CriptoAnlise ......................................................................... 21
Tabela 3: Tempo mdio para busca de chave [12] ................................................... 22

LISTA DE ABREVIATURAS E SIGLAS

AC - Autoridade Certificadora
ADT Android Development Tools (Ferramentas de Desenvolvimento Android)
AES Advanced

Data Encryption Standard (Padro de Criptografia de Dados

Avanada)
AVD Android Virtual Device (Dispositivo Virtual Android)
API - Application Programming Interface (Interface de Programao de Aplicativos)
DES - Data Encryption Standard (Padro de Criptografia de Dados)
3-DES - Triple Data Encryption Standard (Padro de Criptogtafia de Dados Triplo)
GPS Global Positioning System (Sistema de Posicionamento Global)
IDE Integrated Development Environment (Ambiente de Desenvolvimento Integrado)
MAC Message Authentication Code (Codigo de Autenticao de Mensagem)
PKCS - Public-Key Cryptography Standards (Padres de Criptografia de Chave Pblica)
PKI Public Key-Infrastructure (Infra Estrutura de Chave Pblica)
SDK Software Development Kit (Conjunto de Desenvolvimento de Software)
UML Unified Modeling Language (Linguagem de Modelagem Unificada)
XML Extensible Markup Language (Linguagem de Marcao Extensivel)

SUMRIO

RESUMO

ABSTRACT

LISTA DE ILUSTRAES

LISTA DE TABELAS

10

LISTA DE ABREVIATURAS E SIGLAS

11

1INTRODUO

14

1.1 MOTIVAO

14

1.2 OBJETIVO

15

1.3 ORGANIZAO DO TRABALHO

15

2 CRIPTOGRAFIA

16

2.1 DEFINIO

16

2.2 CRIPTOGRAFIA SIMTRICA

17

2.2.1 FUNCIONAMENTO ................................................................................. 17


2.3

CRIPTOGRAFIA ASSIMTRICA

23

2.3.1 FUNCIONAMENTO ................................................................................. 24


2.3.2 ALGORITMO RSA................................................................................... 26
2.4 AUTENTICAO DE MENSAGENS E FUNES HASH

28

2.4.1 FUNCIONAMENTO DA AUTENTICAO DE MENSAGEM .................. 28


2.4.2 FUNCIONAMENTO DA FUNO HASH ................................................ 29
2.5 ASSINATURA DIGITAL

30

2.5.1 INFRA ESTRUTURA DE CHAVE PBLICA ........................................... 31


3 ANDROID

33

3.1 DESCRIO DA ARQUITETURA

33

3.2 AMBIENTE DE DESENVOLVIMENTO

35

3.2.1 INSTALANDO O AMBIENTE DE DESENVOLVIMENTO ........................ 36


3.2.2 ANDROID VIRTUAL DEVICE.................................................................. 36
3.3 VISO DE UM APLICATIVO
4 ASSINADOR DIGITAL
4.1

LEVANTAMENTO DOS REQUISITOS

38
40
40

4.1.1 Requisitos Funcionais ............................................................................. 41


4.1.2 Requisitos No Funcionais ...................................................................... 41
4.2 MODELAGEM DO SISTEMA

42

4.3 IMPLEMENTAO

47

4.4 TESTES REALIZADOS

49

5 CONCLUSES E TRABALHOS FUTUROS

51

REFERNCIAS BIBLIOGRFICAS

52

APNDICE Cdigo Fonte Assinador Digital

54

14

1 INTRODUO

Em um mundo cada vez mais interconectado atravs de sistemas computacionais ningum duvida de que a segurana de computadores importante, mas o
que muitas vezes passa despercebido que tcnicas de segurana possam facilitar
o nosso dia a dia e aumentar a nossa produtividade.
Uma tcnica de segurana computacional capaz de incrementar a produtividade a Assinatura Digital, pois garante a autenticidade e a integridade do documento, alm de acelerar o processo de obteno da assinatura. Um exemplo seria
uma empresa que necessita da assinatura de um gerente de operaes para fechar
um contrato, supondo que este estava sendo negociado h meses pode ocorrer de,
exatamente neste perodo, o gerente encontrar-se viajando.
A soluo para esse problema atravs do processo convencional seria enviar esse documento ao gerente que receberia, assinaria e retornaria o documento,
possivelmente atravs do correio, levando alguns dias para que o negcio pudesse
ser concretizado. Utilizando a Assinatura Digital o gerente receberia o documento e
o assinaria digitalmente, retornando-o atravs de email, dessa forma o negcio seria
fechado no mesmo dia e possivelmente na mesma hora.

1.1

MOTIVAO

Atualmente, o poder computacional dos dispositivos mveis como tablets,


celulares e at mesmo televises permitem aplicaes extremamente avanadas e
complexas. Procurando no principal local para aplicativos Android, o Google Play,

15

foram encontrados poucos aplicativos relacionados com a Assinatura Digital e os


poucos encontrados no utilizam tcnicas criptogrficas, sendo apenas uma espcie
de scanner da assinatura manuscrita. O desenvolvimento de um aplicativo para Android de Assinaturas digitais ir proporcionar segurana e mobilidade para aqueles
que o utilizarem.

1.2

OBJETIVO

O objetivo deste trabalho estudar e apresentar as tcnicas utilizadas


para a realizao de assinatura digital de documentos eletrnicos, bem como implementar um assinador digital utilizando o sistema Android de dispositivos mveis.
Idealizar e projetar um assinador que tenha as principais caractersticas de segurana e a simplicidade necessrias para a utilizao por um usurio leigo.

1.3

ORGANIZAO DO TRABALHO

O trabalho foi organizado da seguinte forma. O captulo 2 apresenta a


teoria necessria para o entendimento da criptografia utilizada no processo de assinatura digital. O captulo 3 apresenta o Android, sua organizao e as ferramentas
necessrias para o desenvolvimento de um aplicativo. O captulo 4 apresenta o software desenvolvido como objetivo deste trabalho. No captulo 5 so apresentadas as
concluses e indicaes para trabalhos futuros.

16

2 CRIPTOGRAFIA

A Criptografia existe h milhares de anos, mas com o avano dos computadores e principalmente da Internet adquiriu importncia vital para a vida cotidiana.
Mesmo pessoas comuns j ouviram algo a respeito de Criptografia, hackers, vrus,
ameaas e fraudes na Internet.
Mesmo com tanta divulgao sobre segurana e criptografia, poucas pessoas conhecem o seu verdadeiro significado, por isso ainda existe tanto receio em
transaes efetuadas na Internet.
Neste captulo ser apresentado o conhecimento terico necessrio para o
entendimento da criptografia e, principalmente, para o entendimento da assinatura
digital.

2.1

DEFINIO

Criptografia a cincia que estuda a transformao de uma mensagem


legvel em uma ininteligvel, permitindo que somente os destinatrios dessa mensagem tenham acesso mesma. A palavra criptografia deriva das palavras gregas
kryptos e graphos que significa secreto e grafia, respectivamente.
Com o advento do computador a Criptografia passou, principalmente, a
estudar os sistemas criptogrficos que pudessem ser implementados por essas mquinas, como exemplo tem-se o DES (Data Encryption Standard) [13], 3-DES (Triple
Data Encryption Standard) [14], AES (Advanced Encryption Standard) [15] e outros
algoritmos que necessitam de um computador para serem implementados.
O objetivo da criptografia, de acordo com Stallings [12], proporcionar
alguns mecanismos de segurana como :

17

Confidencialidade apenas pessoas ou entidades autorizadas podem ter


acesso a mensagem ou aos dados;

Autenticao as entidades que participam de uma comunicao so quem


elas afirmam ser.

Integridade garante que a mensagem ou os dados no foram alterados, ou


seja, o destinatrio tem certeza de que recebeu a mensagem original.

No-repdio garante que uma entidade participou de uma determinada


comunicao, por exemplo: um cliente utiliza um sistema home broker para
compra de aes e aps ver o preo das aes despencarem ele nega ter
efetuado tal compra, precisando-se do mecanismo de no-repdio para provar que ele efetivamente comprou as aes.

2.2

CRIPTOGRAFIA SIMTRICA

A criptografia simtrica [12] tambm conhecida como criptografia de


chave privada, pois se utiliza de uma chave secreta para criptografar a mensagem e
esta mesma chave precisa ser usada para decriptografar a mensagem. Como a chave privada precisa ser compartilhada entre o emissor e o destinatrio, manter esta
chave segura imprescindvel para o sucesso da criptografia.

2.2.1 FUNCIONAMENTO

A criptografia simtrica utiliza um algoritmo reversvel, ou seja, permite a


criptografia e esse mesmo algoritmo aplicado de forma inversa mensagem cifrada
ir decriptograf-la fornecendo o texto claro. Alm do algoritmo para criptografar a
mensagem precisamos de uma chave secreta que ser compartilhada pelo emissor
e destinatrio. Este sistema est representado na Figura 1.

18

Figura 1: Esquema de Criptografia Simtrica

Para exemplificar o funcionamento da criptografia simtrica ser utilizada


a Cifra de Csar [16]. Esta cifra muito simples e era utilizada pelos romanos para
ocultar as suas mensagens, a cifra consiste em deslocar as letras em trs posies,
no lugar do A tem-se o D, do B coloca-se o E e assim por diante. No lugar do Z usase o C para completar a cifra, como exemplo o texto claro Roma vai invadir o Egito
ficaria urpd ydl lqydglu r hjlwr.
Para decriptografar essa mensagem usa-se a mesma ideia s que deslocando as letras para o lado inverso, assim no lugar do D tem-se o A e no lugar do A
tem-se o X. Sendo associado um nmero a cada letra, por exemplo A = 1, B = 2, ...,Z
= 26, pode-se representar essa cifra de forma matemtica da seguinte maneira:

Onde:
C = texto cifrado
T = texto claro

,e

19

Para obter-se o texto claro usa-se a funo inversa da utilizada para cifrar
o texto. Como a Cifra de Csar usa sempre a mesma substituio (o nmero 3 que
representa o deslocamento) o mesmo texto ser cifrado sempre da mesma maneira,
assim fica fcil descobrir a mensagem original. Para aumentar a segurana da cifra
pode-se introduzir uma chave, que nesse caso ser o nmero de deslocamentos,
assim matematicamente temos:

,e

Onde:
C = texto cifrado
T = texto claro
k = chave

Esse processo de utilizar uma chave aumenta a segurana da cifra, pois existem agora 26 maneiras diferentes de se criptografar a mesma mensagem dependendo da chave utilizada. A Tabela 1 mostra todas as formas cifradas do mesmo
texto dependendo da chave.
O adversrio que quiser tentar adivinhar a cifra, agora ter que descobrir a
chave utilizada para a criptografia.

20

Texto Claro

Chave

Texto Cifrado

Roma vai invadir o Egito

spnb wbj jowbejs p fhjup

Roma vai invadir o Egito

tqoc xck kpxcfkt q gikvq

Roma vai invadir o Egito

urpd ydl lqydglu r hjlwr

Roma vai invadir o Egito

vsqe zem mrzehmv s ikmxs

Roma vai invadir o Egito

wtrf afn nsafinw t jlnyt

Roma vai invadir o Egito

xusg bgo otbgjox u kmozu

Roma vai invadir o Egito

yvth chp puchkpy v lnpav

Roma vai invadir o Egito

zwui diq qvdilqz w moqbw

Roma vai invadir o Egito

axvj ejr rwejmra x nprcx

Roma vai invadir o Egito

10

bywk fks sxfknsb y oqsdy

Roma vai invadir o Egito

11

czxl glt tyglotc z prtez

Roma vai invadir o Egito

12

daym hmu uzhmpud a qsufa

Roma vai invadir o Egito

13

ebzn inv vainqve b rtvgb

Roma vai invadir o Egito

14

fcao jow wbjorwf c suwhc

Roma vai invadir o Egito

15

gdbp kpx xckpsxg d tvxid

Roma vai invadir o Egito

16

hecq lqy ydlqtyh e uwyje

Roma vai invadir o Egito

17

ifdr mrz zemruzi f vxzkf

Roma vai invadir o Egito

18

jges nsa afnsvaj g wyalg

Roma vai invadir o Egito

19

khft otb bgotwbk h xzbmh

Roma vai invadir o Egito

20

ligu puc chpuxcl i yacni

Roma vai invadir o Egito

21

mjhv qvd diqvydm j zbdoj

Roma vai invadir o Egito

22

nkiw rwe ejrwzen k acepk

Roma vai invadir o Egito

23

oljx sxf fksxafo l bdfql

Roma vai invadir o Egito

24

pmky tyg gltybgp m cegrm

Roma vai invadir o Egito

25

qnlz uzh hmuzchq n dfhsn

Roma vai invadir o Egito

26

roma vai invadir o egito

Tabela 1: Exemplo de Cifra utilizando Chave

21

Texto Cifrado

Chave

Possvel Texto Claro

bywk fks sxfknsb y oqsdy

axvj ejr rwejmra x nprcx

bywk fks sxfknsb y oqsdy

zwui diq qvdilqz w moqbw

bywk fks sxfknsb y oqsdy

yvth chp puchkpy v lnpav

bywk fks sxfknsb y oqsdy

xusg bgo otbgjox u kmozu

bywk fks sxfknsb y oqsdy

wtrf afn nsafinw t jlnyt

bywk fks sxfknsb y oqsdy

vsqe zem mrzehmv s ikmxs

bywk fks sxfknsb y oqsdy

urpd ydl lqydglu r hjlwr

bywk fks sxfknsb y oqsdy

tqoc xck kpxcfkt q gikvq

bywk fks sxfknsb y oqsdy

spnb wbj jowbejs p fhjup

bywk fks sxfknsb y oqsdy

10

roma vai invadir o egito

bywk fks sxfknsb y oqsdy

11

qnlz uzh hmuzchq n dfhsn

bywk fks sxfknsb y oqsdy

12

pmky tyg gltybgp m cegrm

bywk fks sxfknsb y oqsdy

13

oljx sxf fksxafo l bdfql

bywk fks sxfknsb y oqsdy

14

nkiw rwe ejrwzen k acepk

bywk fks sxfknsb y oqsdy

15

mjhv qvd diqvydm j zbdoj

bywk fks sxfknsb y oqsdy

16

ligu puc chpuxcl i yacni

bywk fks sxfknsb y oqsdy

17

hft otb bgotwbk h xzbmh

bywk fks sxfknsb y oqsdy

18

jges nsa afnsvaj g wyalg

bywk fks sxfknsb y oqsdy

19

ifdr mrz zemruzi f vxzkf

bywk fks sxfknsb y oqsdy

20

hecq lqy ydlqtyh e uwyje

bywk fks sxfknsb y oqsdy

21

gdbp kpx xckpsxg d tvxid

bywk fks sxfknsb y oqsdy

22

fcao jow wbjorwf c suwhc

bywk fks sxfknsb y oqsdy

23

ebzn inv vainqve b rtvgb

bywk fks sxfknsb y oqsdy

24

daym hmu uzhmpud a qsufa

bywk fks sxfknsb y oqsdy

25

czxl glt tyglotc z prtez

bywk fks sxfknsb y oqsdy

26

bywk fks sxfknsb y oqsdy

Tabela 2: Exemplo de CriptoAnlise

22

Uma possvel forma de descobrir o texto original tentar todas as chaves


possveis at se obter um texto claro. Utilizando como exemplo o texto cifrado obtido
com a chave = 10 e tentando decriptograf-lo com todas as chaves possveis obtmse a Tabela 2.
Ento conhecendo o algoritmo utilizado na criptografia podem-se tentar todas
as chaves para obter um resultado provvel para o texto claro, essa tcnica conhecida como ataque de fora bruta. Para aumentar a segurana utilizam-se chaves maiores, com isso o tempo para utilizar todas as chaves possveis acaba ficando
invivel. A tabela abaixo fornece o tempo mdio para se descobrir uma chave levando em considerao que cada tentativa leva 1
levar 1

e depois que cada

tentativas

Tamanho da cha-

N de chaves

ve(bits)

Tempo mdio
1 tentativa /

Tempo mdio
tentativas /

32

35,8 minutos

2,15 milisegundos

56

1142 anos

10,01 horas

128
168
Tabela 3: Tempo mdio para busca de chave [12]

O aumento do nmero de tentativas por microssegundo est relacionado com


o aumento da capacidade de processamento dos computadores, ento quando se
escolhe um sistema criptogrfico no se acredita que ele inquebrvel e sim que
ele computacionalmente seguro.
Para um sistema criptogrfico ser computacionalmente seguro, ele precisa ter
um custo para quebrar a cifra superior ao valor da informao protegida ou que o
tempo exigido para obter a informao seja superior a vida til da informao.
A cifra de Csar apresenta um mtodo conhecido por substituio [12]. Observando o texto claro e o cifrado de chave = 10 v-se que todas as letras A foram
substitudas pela letra K, apesar desse processo ter sido utilizado por bastante tempo muito fcil descobrir o texto claro utilizando a frequncia das letras. Isto feito
da seguinte forma:

23

1 descobrindo as frequncias das letras num texto na linguagem desejada,


no nosso caso o portugus;
2 realizando uma contagem de frequncia no texto cifrado;
3 comparando os dois padres e obtendo provveis textos claros;
4 decidindo qual texto claro pode ser a informao desejada.

Para evitar este tipo de ataque utiliza-se outra tcnica de criptografia, conhecida como transposio [12], que consiste em permutar as letras da mensagem. Assim, por exemplo, a palavra touca poderia ficar : touac,otuca,catou e assim por
diante. Ainda pode-se aplicar a anlise de frequncia, mas se teria mais dificuldade
de encontrar o texto claro.
Os sistemas criptogrficos atuais utilizam combinaes dessas duas tcnicas
para aumentar a eficcia [12]. Outra mudana foi com relao ao segredo dos algoritmos, como visto com o exemplo do tamanho da chave, se as chaves forem suficientemente grandes pode-se deixar o algoritmo conhecido. Essa atitude apresenta
como vantagem permitir que a comunidade de criptoanalistas estude e ataque o algoritmo, divulgando informaes sobre falhas e possveis melhorias mantendo o algoritmo seguro, sendo o ataque de fora bruta a nica maneira de quebr-lo.
A criptografia simtrica ideal para manter a confidencialidade de arquivos e
dados, a grande questo como manter a chave secreta e principalmente como
compartilh-la de uma forma segura.

2.3

CRIPTOGRAFIA ASSIMTRICA

Tambm conhecida como criptografia de chave pblica, caracterizada


por utilizar uma chave para criptografia e uma chave diferente para decriptografia
[12]. Com a criptografia assimtrica alm da confidencialidade pode-se conseguir a
autenticao do emissor, podendo esse sistema ser utilizado para assinaturas digitais.
Como requisito para o funcionamento da criptografia assimtrica faz-se
necessrio encontrar uma funo unidirecional com segredo, ou seja:

24

( )
( )

Como visto no esquema acima, a resoluo de uma funo deve ser


computacionalmente fcil, mas a funo inversa tem de ser computacionalmente
difcil. Um exemplo dessa funo unidirecional a multiplicao de dois nmeros
primos grandes, o que computacionalmente fcil de obter. J a funo inversa que
seria a fatorao de um nmero grande em seus fatores primos, tambm grandes,
exige grande esforo computacional. Por essa razo, esta a funo utilizada no
algoritmo de criptografia assimtrica mais conhecido.

2.3.1 FUNCIONAMENTO

O funcionamento bsico da criptografia assimtrica est descrito nos passos


que seguem e pode ser observado na Figura 2:

1- Cada usurio gera um par de chaves


2- Cada usurio torna uma chave pblica e permanece com outra privada
3- Para o emissor enviar uma mensagem confidencial, ele criptografa a mensagem com a chave pblica do destinatrio.
4- Somente o destinatrio pode decriptografar a mensagem usando a sua
chave privada.

25

Figura 2: Esquema de Criptografia Assimtrica

Este o funcionamento bsico que fornece a mesma funo da criptografia


simtrica. Pode-se estender a funcionalidade da criptografia assimtrica fornecendo
a possibilidade de utilizar autenticao. Se um emissor criptografar uma mensagem
com a sua chave privada, qualquer um poder ler essa mensagem utilizando a sua
chave pblica, mas o destinatrio ter certeza de quem enviou a mensagem desde
que o emissor mantenha a sua chave privada segura.
O problema dessa abordagem que essa mensagem no possui confidencialidade, pois qualquer pessoa poderia ler a mensagem. A soluo para este problema
est em realizar uma criptografia dupla, primeiro o emissor criptografa a mensagem
com a sua chave privada e depois com a chave pblica do destinatrio. Agora somente o destinatrio ter acesso ao contedo da mensagem decriptografando-a com
a sua chave privada, e a seguir ele continua a decriptografar com a chave pblica do
emissor para confirmar a origem da mensagem.
O algoritmo de criptografia assimtrica tambm fornece a integridade de uma
mensagem, ou seja, o destinatrio pode ter certeza de que a mensagem no foi alterada. Essa caracterstica obtida atravs da assinatura digital que se utiliza dos
conceitos apresentados anteriormente com mais alguns detalhes que sero apresentados nas Sees 2.4 e 2.5.

26

2.3.2 ALGORITMO RSA

O mtodo de criptografia assimtrica foi apresentado pela primeira vez


em 1976 por Whitfield Diffie e Martin Hellman [2], eles apresentaram apenas a base
terica deste mtodo faltando apresentar um algoritmo com aplicao prtica. Assim,
em

1978,

trs

professores

do

Instituto

MIT,

Ronald

Ri-

vest, Adi Shamir e Leonard Adleman apresentaram um algoritmo conhecido como


RSA [12] devido as iniciais de seus sobrenomes.
Este foi o primeiro algoritmo a ser utilizado para a criptografia assimtrica
e ainda hoje o mais famoso e o mais utilizado.

2.3.2.1 DESCRIO

A criptografia e a decriptografia realizada em blocos, ou seja, se o tamanho


da mensagem for maior que o do bloco, essa mensagem dividida em vrios blocos
e cada bloco vai sendo cifrado at termos a mensagem completamente cifrada [12].
A criptografia tem a seguinte forma:

Onde:
C = texto cifrado,
M = texto claro,
n = nmero escolhido,

27

e = expoente conhecido pelo emissor,


d = expoente conhecido pelo receptor.

O valor de n conhecido pelo emissor e pelo receptor, assim a chave pblica


ser PU = {e,n} e a chave privada PR = {d,n}. Para que esse algoritmo funcione deve
ser possvel encontrar valores de e, d e n que satisfaam a ltima equao apresentada. Consegue-se isso usando a funo totiente de Euler ( ) [12] e de acordo com
a teoria dos nmeros para que

, para todo M < n, d e e tem que ser

inversos multiplicativos mod ( ), ento :

( ).

Da teoria dos nmeros sabe-se tambm que (

)(

), sendo p e

q nmeros primos, assim o nosso n passa a ser pq, onde lembrando da descrio
de criptografia assimtrica sobre funo unidirecional sabe-se que calcular n = pq
computacionalmente fcil, mas dado um n grande encontrar p e q computacionalmente difcil.
O algoritmo utilizado para a gerao de chaves o seguinte:
1. Selecione p e q primos
2. Calcule n = p x q
3. Calcule ( )

)(

4. Selecione o inteiro e tal que


5. Calcule d,

( )

6. Chave pblica ser PU = {e,n}


7. Chave privada ser PR = {d,n}

( ( ) )

( )

28

2.4

AUTENTICAO DE MENSAGENS E FUNES HASH

A autenticao de mensagens e as funes de hash so tcnicas utilizadas para garantir a integridade dos dados da mensagem transmitida, ou seja, que a
mensagem recebida a mensagem original, garantindo que ela no foi alterada de
nenhuma forma [12]. Alm disso, essas tcnicas ainda permitem a autenticao da
origem.
Para entender a importncia da integridade de dados vamos usar como
exemplo a Cifra de Csar com k = 3, ento a mensagem Roma vai dominar o mundo ser criptografada como urpd ydl grplqdu r pxqgr. Decriptografando essa mensagem, recupera-se a mensagem original, mas o que aconteceria se um oponente
interceptasse a mensagem e enviasse uma mensagem aleatria em seu lugar.
Como exemplo, o texto aleatrio xrta hfgrad lsoms fr gadhjs seria decriptografado como uoqx ecdoxa ipljp co dxaegp, usando o portugus fica fcil de ver
que esta mensagem no tem nenhum significado. Muitas vezes as mensagens criptografadas so apenas padres de bits e o reconhecimento se uma mensagem tem
significado ou no difcil de ser automatizado.
Utilizando uma funo de autenticao de mensagem ou uma funo hash
tem-se a confiana necessria de que a mensagem recebida foi a mensagem enviada, como ser visto nas Sees 2.4.1 e 2.4.2.

2.4.1 FUNCIONAMENTO DA AUTENTICAO DE MENSAGEM

A autenticao de mensagem usa uma funo de comprimento fixo, chamada MAC (cdigo de autenticao de mensagem), tambm conhecida como soma
de verificao criptogrfica, que se utiliza de uma chave para gerar um pequeno bloco de dados [12]. Este bloco anexado junto mensagem, ento bloco e mensagem so criptografados e enviados ao destinatrio.

29

Aps decriptografar a mensagem, o destinatrio separa a mensagem do


MAC. Utilizando a mesma chave, ele calcula o MAC da mensagem recebida e, se
este for igual ao MAC recebido, a mensagem no foi alterada.
A chave da funo MAC precisa permanecer secreta, sendo do conhecimento apenas do emissor e do destinatrio. Dessa maneira, se um oponente interceptar a mensagem e gerar uma mensagem aleatria, no conseguir gerar o MAC
correto por desconhecer a chave.
Como a funo MAC ser calculada novamente no destino, esta funo
no precisa ser reversvel. Utilizada dessa forma, a mensagem agora possui confidencialidade, fornecida pela criptografia, autenticao, somente o emissor que possua a chave k pode gerar um MAC correto, e integridade da mensagem, nos garantindo que ela no foi alterada.

2.4.2 FUNCIONAMENTO DA FUNO HASH

A funo hash, tambm conhecida como sntese de mensagem ou valor de


hash, uma funo de todos os bits da mensagem, ou seja, se um bit for alterado ir
mudar o cdigo hash. A principal diferena da funo hash e a funo MAC est no
fato da funo hash no utilizar uma chave, o hash calculado apenas utilizando a
mensagem como entrada [12].
Calcula-se o valor de hash de uma mensagem, esse hash anexado a
mensagem, e aps isso, a mensagem criptografada e enviada ao destinatrio. A
autenticao obtida similar a que consegue-se usando a funo MAC.
Outra forma de se autenticar uma mensagem seria apenas criptografar o
valor de hash, note-se que dessa forma no existe a confidencialidade, mas o custo
computacional reduzido. O principio da assinatura digital consiste em criptografar o
valor de hash com a chave privada do emissor usando criptografia assimtrica.
Utilizando a funo hash, dessa forma, garante-se a integridade do documento e que apenas o emissor poderia ter criptografado aquele hash, note-se que
para uma assinatura digital no necessrio que o documento esteja criptografado.

30

2.5

ASSINATURA DIGITAL

A assinatura digital [12] foi desenvolvida pensando-se em substituir a assinatura de papel e como forma de resolver uma disputa entre duas partes envolvidas,
Stallings afirma: Uma assinatura digital uma tcnica de autenticao que tambm
inclui medidas para impedir a retratao pela origem. [12,p.227].
Possuindo um formato digital ela apresenta algumas caractersticas intrnsecas a esse formato. Os requisitos para uma assinatura digital [12] que ela seja
capaz de:

Verificar o autor.

Autenticar o contedo no momento da assinatura, fornecendo a confiana da


integridade do documento.

Permitir que terceiros consigam verific-la para resoluo de disputas.

Garantir a irretratabilidade da assinatura, ou seja, o assinante no pode negar que efetuou a mesma (no-repdio).

O princpio da assinatura digital , basicamente, calcular um valor de hash,


criptograf-lo com a chave privada do emissor e anexar esse valor ao documento
eletrnico. Este processo garante a integridade do documento e verifica a identidade
do autor, mas em alguns casos onde a tempestividade importante utiliza-se um
carimbo de tempo [9]. Terceiros podem verificar a assinatura utilizando a chave pblica do emissor de acordo com o processo a seguir:
I.

A calcula o hash de uma mensagem que ele deseja assinar;

II.

A criptografa esse hash com a sua chave privada e anexa a mensagem;

III.

A envia a mensagem assinada para B;

IV.

B utiliza a chave pblica de A para decriptografar o hash anexado;

V.

B calcula o valor hash da mensagem e compara com o valor hash recebido;

31

VI.

Se os valores forem iguais, a assinatura vlida e somente A poderia


ter assinado, pois somente A possui a chave privada.

O processo apresentado no garante a confidencialidade da informao e


ainda apresenta o problema de que A pode negar ter enviado a mensagem afirmando que a sua chave privada foi comprometida. Visando garantir a irretratabilidade
utiliza-se o princpio do terceiro confivel, ou seja, uma entidade neutra que ser o
arbitro da disputa. Para esse fim foi desenvolvido a Infra-Estrutura de Chaves Pblicas.

2.5.1 INFRA ESTRUTURA DE CHAVE PBLICA

Stallings [12] afirma que: A RFC 2822 (Internet Security Glossary) define
a infra-estrutura de chave pblica (PKI Public Key-Infrastructure) como o conjunto
de hardware, software, pessoas, polticas e procedimentos necessrios para criar,
gerenciar, armazenar, distribuir e revogar certificados digitais com base na criptografia assimtrica. Apesar dessa definio ser bastante completa preciso entender o
significado de certificado digital para uma melhor compreenso do que vem a ser
uma Infra-Estrutura de chave pblica.
O certificado digital um arquivo eletrnico que apresenta a identificao
do seu proprietrio e a sua chave pblica, e utilizado para divulgar a chave pblica
do usurio a todos que necessitem verificar as assinaturas digitais realizadas por
esse usurio [12]. utilizado como garantia de que a chave pblica utilizada na verificao da assinatura no foi alterada por terceiros.
Um exemplo de aplicao desse conceito seria um documento de doao
de A para C, onde esse documento tem de ser apresentado a B para que tenha eficcia. Se C gerar um par de chaves qualquer assinando o documento, C poderia
informar a B que aquela chave pblica gerada pertence a A, falsificando o documento. Para evitar esse tipo de falsificao utilizam-se os certificados digitais.
Como visto no exemplo anterior, a distribuio de chave pblica tem de
ser feita de uma maneira confivel. Para resolver este problema e o problema da

32

irretratabilidade utilizada uma Autoridade Certificadora (AC). Esta Autoridade tem


como responsabilidade emitir os certificados digitais utilizados por seus usurios,
garantindo que eles sejam vlidos.
Voltando ao exemplo da doao, B recorreria a Autoridade Certificadora
para saber qual a chave pblica de A e se esta vlida, assim A no pode negar
que tenha assinado o documento e este tambm no pode ser falsificado. Caso a
chave privada de A seja comprometida, A ir informar a Autoridade Certificadora que
ser responsvel por revogar o certificado de A.
Para que no seja necessrio entrar em contato com a Autoridade Certificadora toda vez que uma assinatura seja efetuada, os certificados so assinados
com a chave privada da AC. Assim, basta utilizar a chave pblica da AC para verificar que um certificado vlido.

33

3 ANDROID

Android uma plataforma de desenvolvimento para aplicativos mveis,


criada pelo Google e mantida e desenvolvida atualmente pela Open HandSet Alliance. Utiliza sistema operacional Linux e a linguagem JAVA para desenvolvimento. O
objetivo da Open HandSet Alliance criar uma plataforma nica para diversos dispositivos mveis permitindo que os aplicativos possam ser criados uma nica vez e
distribudos para o maior nmero de equipamentos e modelos [7].

3.1

DESCRIO DA ARQUITETURA

Android construdo como uma pilha de softwares com vrias camadas


uma sobre a outra com as camadas dos nveis inferiores fornecendo servios para
as camadas superiores. Uma viso de alto nvel desta pilha vista na Figura 3, a
camada que est na base o ncleo do sistema operacional Linux, acima desta encontra-se as bibliotecas C e a mquina virtual Dalvik, as duas camadas seguintes
so as bibliotecas JAVA e a camada no topo que possui as aplicaes utilizadas pelos usurios [11].
O Kernel 2.6 do Linux foi utilizado como sistema operacional, ele responsvel pelo gerenciamento do hardware, memria, processos e todas as outras
atividades que so delegadas ao sistema operacional. Assim o desenvolvedor no
precisa se preocupar em como acessar e gerenciar dispositivos, bastando solicitar
ao sistema operacional os dispositivos prontos para uso. A utilizao do kernel do
Linux permite aos fabricantes produzir drivers para um ambiente conhecido [11].

34

Figura 3 : Viso Alto Nvel da Pilha de Software Android [5]

As bibliotecas C/C++ so OpenGL, WebKit, FreeType, Secure Sockets


Layer (SSL) entre outras. Essas bibliotecas so construdas com base na Berkeley
Software Distribution (BSD) e otimizadas para funcionar com sistemas embarcados
que utilizam Linux [7].
O Android no possui uma mquina virtual JAVA e sim uma mquina virtual otimizada que requer pouca memria chamada DALVIK. O desenvolvedor escreve um programa JAVA normalmente, mas aps gerar o bytecode (.class) ele precisa ser convertido para o formato .dex (Dalvik Executable). Por fim, rene-se os arquivos .dex com outros recursos, como imagens e udios, em um nico pacote .apk
(Android Package File) [13] .
As bibliotecas JAVA que se encontram na camada acima da mquina virtual Dalvik fornecem os servios necessrios para o desenvolvimento das aplicaes

35

Android como acesso a internet, banco de dados, cmera, GPS, interfaces grficas e
outros.
No topo da pilha encontram-se as aplicaes que o usurio pode utilizar e
nesta camada que o aplicativo desenvolvido neste trabalho ir se localizar. Um
diferencial do Android para outras plataformas de dispositivos mveis que no h
diferena entre uma aplicao nativa do sistema e outra produzida por desenvolvedores independentes, isso garante que uma aplicao independente pode utilizar
todo o poder computacional do dispositivo.

3.2

AMBIENTE DE DESENVOLVIMENTO

Neste trabalho foi utilizado a IDE (Integrated Development Environment)


Eclipse [18], pois existem plugins desenvolvidos pelo Google para este ambiente,
alm de uma documentao extensa de como desenvolver aplicativos com este IDE.
O Eclipse pode ser obtido em [18], o Google recomenda que se utilize a ltima verso classic. Neste trabalho foi utilizado o Eclipse classic 3.7.2.
O Eclipse foi desenvolvido para se escrever aplicaes JAVA, para desenvolver aplicativos Android necessrio o Android SDK (Software Development
Kit) que pode ser obtido em [19] e do ADT (Android Development Tools) plugin que
desenvolvido pelo Google para aproveitar todas as funcionalidades do Eclipse, bem
como oferecer novas funcionalidades necessrias para o desenvolvimento de aplicativos Android [5].
Entre as funcionalidades oferecidas pelo ADT est a possibilidade de executar o emulador de dispositivos Android diretamente do Eclipse, permitindo utilizar o
debug e a visualizao de logs. Outra funcionalidade interessante a criao automtica do arquivo em extenso .apk (Android Package File) permitindo que este arquivo seja assinado digitalmente possibilitando a instalao em um dispositivo real
[7].

36

3.2.1 INSTALANDO O AMBIENTE DE DESENVOLVIMENTO

Para o desenvolvimento deste trabalho foi utilizado o sistema operacional


Windows 7 Professional de 64 bits, por isso o Eclipse 3.7.2 para Windows 64 bits foi
escolhido. Aps isso foi feito o download do Android SDK com o instalador para o
Windows. Esse processo simples e totalmente automtico apenas tendo que seguir o instalador. Para instalar o plugin ADT necessrio inicializar o Eclipse e selecionar o menu Help > Install New Software.
Na tela que ir se abrir digita-se ADT e o Eclipse ir mostrar os repositrios existentes, caso isso no acontea pode-se adicionar um repositrio com a seguinte URL : https://dl-ssl.google.com/android/eclipse/. Aps selecionar os repositrios clica-se em Next e o assistente ir instalar o ADT, quando a instalao estiver
concluda clica-se em Finish e recomenda-se que o Eclipse seja reiniciado.
Aps instalar o ADT necessrio informar ao Eclipse a localizao do
SDK, para isso basta acessar o menu Window>Preferences e selecionar a opo
Android. Na tela que ir aparecer digita-se o caminho correto para o SDK e concluise a configurao do ambiente de desenvolvimento.

3.2.2 ANDROID VIRTUAL DEVICE

Android Virtual Device (AVD) uma configurao virtual de um dispositivo


mvel, a partir desta configurao o emulador criar uma simulao com a mesma
configurao de hardware de um dispositivo real [5].
Ao definir um AVD alm de se criar a definio de hardware necessrio
determinar a verso alvo do Android. Para este trabalho foi definido um AVD com o
Android 2.2 como alvo, 512MB o tamanho do carto de memria e uma tela
WQVGA400, esta configurao apresentada na Figura 4. Cada verso do Android
tem um cdigo identificador, no nosso caso o Android 2.2 identificado pela API level 8.

37

Figura 4 : Tela de configurao AVD

38

3.3

VISO DE UM APLICATIVO

Ao se criar um projeto Android necessrio especificar o nome do projeto, o nome do pacote, o nome da classe que ser criada, a verso alvo do Android e
a verso mnima do SDK necessrio para executar o aplicativo. Uma estrutura de
diretrios pr-definida ser criada como mostrado na Figura 5, bem como alguns
arquivos essenciais a um aplicativo Android.
Apesar de se utilizar a linguagem JAVA no desenvolvimento de aplicativos Android, existem pequenas diferenas e alguns conceitos novos necessrios
para a criao desses programas. Uma diferena essencial est na aplicao do
paradigma MVC (Modelo Viso Controle ) [1]. Todo aplicativo Android possui um
arquivo XML responsvel pela apresentao visual, uma Activity que a classe responsvel por captar as interaes com o usurio e as outras classes JAVA que correspondem ao modelo da aplicao. A classe Activity criada por padro no Eclipse
exibe o clssico texto Hello World e o nome do projeto.
Todo o layout de uma tela feito atravs de um arquivo XML, quais componentes sero utilizados, seu posicionamento, as cores da tela, as imagens e todos
os detalhes do layout esto nesse arquivo. Para que esta tela seja exibida necessitase de uma Activity que a classe responsvel por definir qual View ser desenhada
na tela e por controlar os eventos desta [7].

39

Figura 5 : Viso da Estrutura de um Projeto Android

Na estrutura vista na Figura 5 os diretrios e arquivos mais importantes


so:

src Esta pasta contm todas as classes utilizadas no projeto.

gen Esta pasta possui uma classe, R.java, gerada automaticamente com a finalidade de permitir o acesso das classes dos projetos aos recursos como arquivos e imagens.

res Esta pasta possui os recursos do aplicativo. As subpastas


drawable armazenam as imagens separadas pela resoluo da tela, a subpasta layout armazena os arquivos responsveis pela interface grfica e a subpasta values contm os arquivos XML responsveis pela internacionalizao.

AndroidManifest.xml o arquivo responsvel pelas configuraes principais da aplicao.

40

4 ASSINADOR DIGITAL

O aplicativo desenvolvido possibilita a assinatura digital, bem como a verificao de uma assinatura utilizando dispositivos mveis que possuam o sistema
Android, essa verificao garante a integridade e a autenticidade do documento. A
assinatura efetuada utilizando o hash SHA1 com o algoritmo de chave assimtrica
RSA.
Este captulo aborda tanto a modelagem e anlise do software, bem como
a sua implementao. Dois casos de uso foram descritos e utilizados para a elicitao dos requisitos funcionais, j os requisitos no funcionais foram obtidos aps diversos testes e pesquisas. Os diagramas UML foram utilizados para um melhor entendimento do sistema.

4.1

LEVANTAMENTO DOS REQUISITOS

O aplicativo desenvolvido deve permitir a Assinatura de documentos eletrnicos e deve ser capaz de verificar a validade de tais Assinaturas. interessante
notar que documento eletrnico pode ser qualquer arquivo digital, como arquivos de
texto, imagens, udio, vdeos, etc.
Para a realizao da Assinatura necessrio que o usurio possua uma
chave privada e o documento a ser assinado, esta chave privada deve estar armazenada num arquivo PKCS#12. PKCS o acrnimo de Public-Key Cryptography
Standards [4] e PKCS#12 um formato de arquivo utilizado para armazenar chaves
privadas com os seus respectivos certificados de chave pblica. O PKCS#12 tambm pode armazenar apenas certificados e o padro utilizado neste trabalho por
ser o mais utilizado em softwares de Assinatura Digital.

41

As assinaturas geradas so salvas com a extenso .p7s que corresponde


ao padro PKCS#7, este padro o mais utilizado para assinaturas digitais [4].
Para verificar as Assinaturas digitais precisamos do certificado com a
chave pblica do autor da Assinatura, o documento original e a Assinatura propriamente dita. Os certificados devem estar armazenados num arquivo PKCS#12 e a
Assinatura deve possuir a extenso .p7s.

4.1.1 Requisitos Funcionais

O aplicativo deve assinar digitalmente qualquer tipo de arquivo.

O aplicativo deve verificar as assinaturas geradas confirmando a integridade e


a autenticidade dos documentos.

O aplicativo deve ser capaz de recuperar as chaves pblicas dos certificados


para a verificao das assinaturas.

O aplicativo deve ser capaz de recuperar as chaves privadas dos arquivos


PKCS#12 para efetuar as assinaturas.

As assinaturas digitais devem ser geradas utilizando o algoritmo RSA e funo hash SHA1.

4.1.2 Requisitos No Funcionais

O Assinador Digital precisa de um dispositivo mvel com sistema Android 2.2


ou superior.

O Assinador Digital deve ser capaz de ler e utilizar arquivos no formato


PKCS#12.

As assinaturas geradas devem utilizar a extenso .p7s e no devem estar encapsuladas com o documento original.

42

4.2

MODELAGEM DO SISTEMA

A Linguagem de Modelagem Unificada(UML) uma linguagem visual


para especificar, construir e documentar os artefatos dos sistemas [6,p.39]. Larman
ainda afirma UML a notao diagramtica padro, de fato, para desenhar ou
apresentar figuras relacionadas a software [6,p.39] .
Os diagramas UML foram utilizados para facilitar a modelagem e o entendimento do aplicativo desenvolvido. Foram criados 4 diagramas, 2 diagramas de
atividades e 2 diagramas de sequncia, para modelar o processo de assinatura e de
verificao de assinaturas.
Casos de uso so narrativas em texto, amplamente utilizadas para descobrir e registrar requisitos [6, p. 87]. Foram descritos dois casos de uso que representam as funcionalidades do aplicativo desenvolvido, assinar e verificar assinaturas
de documentos eletrnicos. Baseando-se nesses casos de uso foram enumerados
os requisitos funcionais e criados diagramas de atividade para facilitar o entendimento do fluxo de acontecimentos.

Figura 6: Diagrama Casos de Uso

Caso de Uso : Assinar Documento


1. O Usurio seleciona o arquivo pkcs12.
2. O aplicativo solicita a senha do arquivo pkcs12.

43

3. O Usurio digita a senha do arquivo pkcs12.


4. O Aplicativo exibe todas as chaves privadas e solicita que o usurio selecione uma.
5. O usurio seleciona a chave privada.
6. O aplicativo solicita a senha da chave privada.
7. O usurio digita a senha da chave privada.
8. O usurio seleciona o documento a ser assinado.
9. O usurio solicita que a assinatura seja efetuada.
10. O aplicativo assina o documento e salva a assinatura com a extenso .p7s no mesmo diretrio do documento.

Fluxo Alternativo :
1a. Arquivo PKCS#12 invlido :
1. Aplicativo informa que o arquivo invlido.
2. Aplicativo solicita que o Usurio selecione outro arquivo.
3a. Senha Incorreta.
1. Aplicativo informa ao Usurio e aguarda que o mesmo digite
nova senha.
7a. Senha Incorreta.
1. Aplicativo informa ao Usurio e aguarda que o mesmo digite
nova senha.

Para este caso de uso foi desenhado um diagrama de atividades apresentado na figura 7. No diagrama est representado apenas o fluxo principal do caso de
uso.

44

Figura 7 : Diagrama de Atividades do Processo de Assinatura

45

Caso de Uso: Verificar Assinatura

1. O usurio seleciona a assinatura que deseja verificar.


2. O usurio seleciona o arquivo pkcs12.
3. O aplicativo solicita a senha do arquivo pkcs12.
4. O Usurio digita a senha do arquivo pkcs12.
5. O Aplicativo exibe todos os certificados e solicita que o usurio selecione um.
6. O usurio seleciona o certificado.
7. O usurio seleciona o documento original.
8. O usurio solicita que a assinatura seja verificada.
9. O aplicativo verifica a assinatura e apresenta a mensagem da verificao.

Fluxo Alternativo :
2a. Arquivo PKCS#12 invlido :
1. Aplicativo informa que o arquivo invlido.
2. Aplicativo solicita que o Usurio selecione outro arquivo.
4a. Senha Incorreta.
1. Aplicativo informa ao Usurio e aguarda que o mesmo digite
nova senha.

Para o caso de uso Verificar Assinatura foi desenhado o diagrama de atividades da figura 8, como no caso de uso anterior foi representado apenas o fluxo
principal .

46

Figura 8 : Diagrama de Atividades do Processo de Verificao de Assinatura

47

4.3

IMPLEMENTAO

O aplicativo desenvolvido apresenta duas funes bsicas: Assinatura e


Verificao de Assinaturas digitais. Estas operaes so realizadas pela classe Assinador.java utilizando a biblioteca java.security para implementar o algoritmo RSA
com o hash SHA 1.
Utilizando o modelo MVC imposto pela arquitetura Android foi criado um
arquivo XML para cada tela do aplicativo, bem como uma classe que estende a classe Activity para funcionar como o controlador de cada tela.
Uma classe Ferramentas.java foi criada para cuidar da leitura e escrita
dos arquivos, nesta classe h trs mtodos. Um mtodo ir escrever, outro ir ler e
um terceiro transforma um arquivo File do JAVA em um array de bytes.
O Android no possui biblioteca para disponibilizar visualizao dos documentos armazenados, por isso foi utilizado um projeto android-filechooser [17],
que teve a classe FileChooser modificada para atender as necessidades do aplicativo.
A classe Assinador.java a classe principal do aplicativo, ela possui dois
mtodos um para assinar documentos e outro para verificar as assinaturas.

Figura 9 : Diagrama de Sequncia do Processo de Assinatura

48

O mtodo assinar() est representado no diagrama de sequncia da Figura 9. A classe Signature utiliza o mtodo getInstance(Sha1WithRSA, BC) para
obter uma instncia que ir utilizar o algoritmo de assinatura RSA com o hash SHA 1
utilizando o provider do BouncyCastle.. Aps isso, esta instncia de Signature inicializada para realizar assinaturas com a chave privada escolhida, utilizando o mtodo initSign(chave). O mtodo update(message) informa o documento que ser assinado e, por fim, o mtodo sign() produz um array de bytes que a assinatura digital.

Figura 10 : Diagrama de Sequncia do Processo de verificao da Assinatura

O mtodo verificar() est representado no diagrama de sequncia da Figura 10 e uma instncia de Signature criada da mesma forma que no mtodo assinar(). A inicializao foi feita com o mtodo initVerify(certificado) utilizando o certificado que possui a chave pblica do autor da assinatura. O mtodo update(message)
funciona da mesma forma que no mtodo assinar() e, por fim, a verificao realizada utilizando-se o mtodo verify(assinatura).

49

Figura 11 : Telas do Aplicativo Desenvolvido

4.4

TESTES REALIZADOS

Para a verificao do Assinador foi utilizado o seguinte roteiro:


1. Criou-se trs arquivos com os seguintes textos Sidney, SidneyLoyola e
Sidney Loyola.
2. Esses arquivos foram salvos em trs formatos diferentes pdf, Word e txt:
a. Sidney.txt,Sidney.docx,Sidney.pdf
b. SidneyLoyola.txt, SidneyLoyola.docx, SidneyLoyola.pdf
c. Sidney Loyola.txt, Sidney Loyola.docx, Sidney Loyola.pdf
3. Todos os arquivos foram assinados digitalmente com o aplicativo, gerando
assinaturas com o mesmo nome do arquivo e extenso p7s.
4. Foram realizadas diversas verificaes com as assinaturas e seus respectivos documentos originais. Alm disso, realizaram-se verificaes com uma
assinatura e um documento que no a originou.

50

Aps os testes constatou-se que o mesmo documento, mas com um formato


diferente (pdf ou txt, por exemplo), gera assinaturas diferentes. A alterao de um
simples espao em um texto gerou uma assinatura diferente, o que garante a integridade do documento. Ainda foram realizados os mesmos testes com um certificado
diferente e o aplicativo funcionou corretamente, garantindo a autenticidade do autor.
Como teste adicional, para verificao de desempenho, foram escolhidos diversos arquivos de vrios tamanhos e foram feitas tentativas para ver se era possvel assin-los digitalmente. Foi anotado o tempo que cada assinatura levou para ser
realizada, desta forma foi obtido os resultados apresentados abaixo:
1. Arquivo

1 KB 3s

2. Arquivo 10 KB 3s
3. Arquivo 100 KB 3s
4. Arquivo 500 KB 7s
5. Arquivo

1 MB 10s

6. Arquivo

5 MB 30s

7. Arquivo 10 MB 82s
8. Arquivo 15 MB 82s
9. Arquivo 16 MB erro.

Experimentalmente chegou-se ao tamanho de 15 MB, ou seja, arquivos maiores de 15 MB apresentaram erro durante o processo de assinatura.
Revisando o cdigo verificou-se que o motivo de tal restrio a transformao do arquivo em um array de bytes que ser assinado, sendo o array o limitador
do tamanho do arquivo a ser assinado. Criando-se o mesmo array de bytes em um
Desktop encontrou-se o mesmo limitador em relao ao tamanho.

51

5 CONCLUSES E TRABALHOS FUTUROS

Neste trabalho foi desenvolvido um aplicativo para Assinaturas Digitais utilizando Android, uma plataforma poderosa e robusta para aplicativos mveis. Para
facilitar o entendimento das Assinaturas Digitais foi realizado um estudo sobre criptografia e as tcnicas necessrias para a aplicao da Assinatura Digital.
Foi apresentada a plataforma Android, bem como o ambiente de desenvolvimento necessrio para a criao do aplicativo utilizando o Eclipse. O emulador
fornecido por esse ambiente foi de grande importncia para o desenvolvimento deste trabalho.
Conclui-se que o Android permite o desenvolvimento e aplicao de tcnicas criptogrficas complexas, mesmo em dispositivos mveis. A programao em
JAVA facilita o aprendizado do Android, bem como oferece bibliotecas bem estruturadas e robustas. O estudo da criptografia permite verificar as condies necessrias
para se garantir a integridade e autenticidade dos documentos eletrnicos.
O dispositivo virtual do Android (AVD) funciona bem e facilita o desenvolvimento permitindo criar diversas configuraes diferentes para a realizao de testes.
A aplicao do processo e das metodologias de Engenharia de Software
adquiridas ao longo do curso facilitou a modelagem e a implementao do aplicativo,
mesmo numa linguagem totalmente nova, como o Android.
Como trabalho futuro pretende-se implementar melhorias no software para
que ele seja capaz de permitir a leitura e a Assinatura em diferentes formatos proporcionando a interoperabilidade com sistemas profissionais de Assinatura Digital,
bem como dar continuidade a este projeto em cursos de ps-graduao.

52

REFERNCIAS BIBLIOGRFICAS

[1]

BURNECK, Steve. Applications Programming in Smalltalk-80: How


to
use
Model-View-Controller
(MVC).
<http://stwww.cs.illinois.edu/users/smarch/st-docs/mvc.html>. Acesso em 24 Jul.
2012.

[2]

DIFFIE, W.; HELLMAN, M. E. New Directions in Cryptography. IEEE


Transactions on Information Theory, IT22, n.6. 1976

[3]

FILHO,
Marcos
Muniz
Calr.
Kerberos.
<http://www.gta.ufrj.br/grad/99_2/marcos/kerberos.htm>. Acesso em 26
Jun. 2012.

[4]

HOOK, David. Beginning Cryptography with Java. Wrox Press.2005.

[5]

KOMATINENI, Satya; MACLEAN, Dave; HASHIMI, Sayed Y. Pro Android


3. APRESS.2011.

[6]

LARMAN, Craig. Utilizando UML e padres: uma introduo anlise e


ao projeto orientado a objetos e ao desenvolvimento interativo. Bookman,
3 edio. 2007.

[7]

LECHETA, Ricardo R. Google Android: Aprenda a criar aplicaes para


dispositivos mveis com o Android SDK. Novatec Editora.2010.

[8]

MEIRELLES, Alexandre Incio. Segurana da Informao. Niteri, 2008.


Trabalho de Concluso de Curso Universidade Federal Fluminense
UFF.

[9]

MOECKE, Cristian Thiago. Assinatura Digital de Documentos Eletrnicos


na ICP-Brasil. Florianpolis, 2008. Monografia de Concluso de Curso
Universidade Federal de Santa Catarina UFSC.

[10] PEREIRA, Davi Garcia. Assinatura Digital de Documentos Eletrnicos em


Dispositivos Mveis. Florianpolis, 2009. Trabalho de Concluso de Curso
Universidade Federal de Santa Catarina UFSC.
[11] SIX, Jeff. Application Security for Android Platform. OREILLY.2012.
[12] STALLINGS, William. Criptografia e segurana de redes. Pearson Prentice Hall, 4 edio. 2005.
[13] <http://pt.wikipedia.org/wiki/Data_Encryption_Standard> acessado em 26
Jun. 2012.

53

[14] <http://pt.wikipedia.org/wiki/3DES> acessado em 26 Jun. 2012.


[15] <http://pt.wikipedia.org/wiki/Advanced_Encryption_Standard>
em 26 Jun. 2012.

acessado

[16] <http://pt.wikipedia.org/wiki/Cifra_de_Csar> acessado em 27 Jun.2012.


[17] <http://code.google.com/p/android-filechooser/> acessado em 28 Jun.
2012.
[18] <http://www.eclipse.org/downloads/> acessado em 28 Jun.2012
[19] <http://developer.android.com/sdk/index.html> acessado em 28 Jun.2012

54

APNDICE Cdigo Fonte Assinador Digital

TelaInicial.java

package br.cederj.tcc.activity;
import android.app.Activity;
import
import
import
import
import
import

android.content.Intent;
android.os.Bundle;
android.util.Log;
android.view.View;
android.widget.Button;
br.cederj.tcc.R;

/**
* @author Sidney Loyola de S
* @version 1.0 Aplicativo desenvolvido para o Trabalho de Concluso de
Curso
*
submetido ao Curso de Tecnologia em Sistemas de Computao da
*
Universidade Federal Fluminense como requisito parcial para obteno
*
do ttulo de Tecnlogo em Sistemas de Computao
*
*/
public class TelaInicial extends Activity {
/** Called when the activity is first created. */
private String CATEGORIA = "ASSINADOR 1.6";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tela_inicial);
Button botaoAssinar = (Button) findViewById(R.id.botaoAssinar);
botaoAssinar.setOnClickListener(new
View.OnClickListener() {
@Override
public void onClick(View v) {
try {

55
Intent intent = new Intent(TelaInicial.this,
TelaAssinaDocumento.class);
startActivity(intent);
} catch (Exception e) {
Log.i(CATEGORIA, "Exceo
Criada " + e.toString());
}
}
});
Button botaoVerificar = (Button) findViewById(R.id.botaoVerificar);
botaoVerificar.setOnClickListener(new
View.OnClickListener() {
@Override
public void onClick(View v) {
try {
Intent intent = new Intent(TelaInicial.this,
TelaVerificaAssinatura.class);
startActivity(intent);
} catch (Exception e) {
Log.i(CATEGORIA, "Exceo
Criada " + e.toString());
}
}
});
}
}

TelaAssinaDocumento.java

package br.cederj.tcc.activity;
import
import
import
import
import
import

android.app.Activity;
android.content.Intent;
android.os.Bundle;
android.util.Log;
android.view.View;
android.widget.AdapterView;

56
import
import
import
import
import
import

android.widget.AdapterView.OnItemSelectedListener;
android.widget.Button;
android.widget.Toast;
br.cederj.tcc.R;
br.cederj.tcc.assinador.Assinador;
cederj.tcc.FileChooser.FileChooser;

/**
* @author Sidney Loyola de S
* @version 1.0
* Aplicativo desenvolvido para o
* Trabalho de Concluso de Curso submetido ao
* Curso de Tecnologia em Sistemas de Computao da
* Universidade Federal Fluminense
* como requisito parcial para obteno do ttulo de
* Tecnlogo em Sistemas de Computao
*
*/
public class TelaAssinaDocumento extends Activity implements OnItemSelectedListener{
String CATEGORIA = "ASSINADOR 1.6";
String
path,aliasCertificado,tipoAssinatura,senha,pathDocumento,senhaAlias;
int ESCOLHA = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tela_assina_documento);
Button botaoEscolherChave = (Button) findViewById(R.id.botao_escolher_chave);
botaoEscolherChave.setOnClickListener(new
View.OnClickListener() {
@Override
public void onClick(View v) {
try {
Intent intent =
new Intent(TelaAssinaDocumento.this,FileChooser.class);
intent.putExtra("tipo", "pkcs12");

startActivityForResult(intent, ESCOLHA);

57

}catch (Exception
e) {
Log.i(CATEGORIA, "Exceo Criada "+e.toString());
}
}
});
Button botaoEscolherDocumento = (Button) findViewById(R.id.botaoEscolherDocumento);
botaoEscolherDocumento.setOnClickListener(new
View.OnClickListener() {
@Override
public void onClick(View v) {
try {
Intent escolherDocumento = new Intent(TelaAssinaDocumento.this,FileChooser.class);
escolherDocumento.putExtra("tipo", "escolherDocumento");
startActivityForResult(escolherDocumento, ESCOLHA);
}catch (Exception
e) {
Log.i(CATEGORIA, "Exceo Criada "+e.toString());
}
}
});
Button botaoAssinaDocumento = (Button) findViewById(R.id.botaoAssinarDocumento);
botaoAssinaDocumento.setOnClickListener(new
View.OnClickListener() {
@Override
public void onClick(View v) {
Assinador assinador = new
Assinador(path, senha, aliasCertificado, pathDocumento,senhaAlias);
try {
assinador.assinar();
Toast.makeText(TelaAssinaDocumento.this, "Assinatura Criada com Sucesso!", Toast.LENGTH_SHORT).show();
} catch (Exception e) {

58
Toast.makeText(TelaAssinaDocumento.this, "Ocorreu um Problema e a Assinatura no pode ser efetuada!", Toast.LENGTH_SHORT).show();
}

}
});
}
@Override
protected void onActivityResult(int codigo, int resultado,Intent it) {
if (codigo == ESCOLHA) {
if(it != null){
Bundle params =
it.getExtras();

if (params != null) {

if(params.getString("tipo").equals("pkcs12")){
path =
params.getString("path");
if(path.endsWith("p12") || path.endsWith("pfx")){
Intent intent = new Intent(TelaAssinaDocumento.this,TelaSolicitarSenhaPKCS12.class);
intent.putExtra("tipo", "obterSenha");
intent.putExtra("path", path);
startActivityForResult(intent, ESCOLHA);
}else{
Toast.makeText(TelaAssinaDocumento.this, "Arquivo Invlido,
Escolha um arquivo pkcs12 vlido!", Toast.LENGTH_SHORT).show();
//
Intent intent = new Intent(TelaAssinaDocumento.this,FileChooser.class);

59

intent.putExtra("tipo", "pkcs12");
startActivityForResult(intent, ESCOLHA);

}
}
if(params.getString("tipo").equals("obterSenha")){
senha =
params.getString("senha");
Intent
nova = new Intent(TelaAssinaDocumento.this,TelaLeituraPKCS12.class);
nova.putExtra("path", path);
nova.putExtra("tipo", "aliasCertificado");
nova.putExtra("senha", senha);
startActivityForResult(nova,ESCOLHA);
}

if(params.getString("tipo").equals("aliasCertificado")){
aliasCertificado = params.getString("alias");
Intent intent = new Intent(TelaAssinaDocumento.this,TelaSelecionarSenhaChavePrivada.class);
intent.putExtra("tipo", "senhaAlias");
intent.putExtra("path", path);
intent.putExtra("senha", senha);
intent.putExtra("alias", aliasCertificado);
startActivityForResult(intent, ESCOLHA);
}
if(params.getString("tipo").equals("senhaAlias")){

60

senhaAlias = params.getString("senhaAlias");
}
if(params.getString("tipo").equals("escolherDocumento")){
pathDocumento = params.getString("path");
}
}
}
}
}
@Override
public void onItemSelected(AdapterView<?> parent, View view,
int pos,
long id) {
tipoAssinatura = (String) parent.getItemAtPosition(pos);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
tipoAssinatura = "Assinatura Separada";
}

TelaVerificaAssinatura.java

package br.cederj.tcc.activity;
import
import
import
import
import
import
import
import
import

android.app.Activity;
android.content.Intent;
android.os.Bundle;
android.util.Log;
android.view.View;
android.widget.Button;
android.widget.Toast;
br.cederj.tcc.R;
br.cederj.tcc.assinador.Assinador;

61
import cederj.tcc.FileChooser.FileChooser;

/**
* @author Sidney Loyola de S
* @version 1.0
* Aplicativo desenvolvido para o
* Trabalho de Concluso de Curso submetido ao
* Curso de Tecnologia em Sistemas de Computao da
* Universidade Federal Fluminense
* como requisito parcial para obteno do ttulo de
* Tecnlogo em Sistemas de Computao
*
*/
public class TelaVerificaAssinatura extends Activity{
private
private
private
private
private
private
private

String
String
String
String
String
String
String

CATEGORIA = "ASSINADOR 1.6";


pathPKCS12;
pathDocumento;
pathAssinatura;
senha;
senhaAlias;
aliasCertificado;

private int ESCOLHA = 1;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tela_verifica_assinatura);

Button botaoEscolherAssinatura = (Button) findViewById(R.id.botaoEscolherAssinatura);


botaoEscolherAssinatura.setOnClickListener(new
View.OnClickListener() {
@Override
public void onClick(View v) {
try {
Intent escolherAssinatura
= new Intent(TelaVerificaAssinatura.this,FileChooser.class);
escolherAssinatura.putExtra("tipo", "assinatura");
startActivityForResult(escolherAssinatura, ESCOLHA);
}catch (Exception e) {

62
Log.i(CATEGORIA,
"Exceo Criada "+e.toString());
}
}
});
Button botaoEscolherCertificado = (Button) findViewById(R.id.botaoEscolherCertificado);
botaoEscolherCertificado.setOnClickListener(new
View.OnClickListener() {
@Override
public void onClick(View v) {
try {
Intent escolherPKCS12 =
new Intent(TelaVerificaAssinatura.this,FileChooser.class);
escolherPKCS12.putExtra("tipo", "certificado");
startActivityForResult(escolherPKCS12, ESCOLHA);
}catch (Exception e) {
Log.i(CATEGORIA,
"Exceo Criada "+e.toString());
}
}
});
Button botaoEscolherDocumentoOriginal = (Button) findViewById(R.id.botaoEscolherDocumentoOriginal);
botaoEscolherDocumentoOriginal.setOnClickListener(new
View.OnClickListener() {
@Override
public void onClick(View v) {
try {
Intent escolherDocumento =
new Intent(TelaVerificaAssinatura.this,FileChooser.class);
escolherDocumento.putExtra("tipo", "escolherDocumento");
startActivityForResult(escolherDocumento, ESCOLHA);
}catch (Exception e) {
Log.i(CATEGORIA,
"Exceo Criada "+e.toString());
}
}
});

63
Button botaoVerificarAssinatura = (Button) findViewById(R.id.botaoVerificaAssinatura);
botaoVerificarAssinatura.setOnClickListener(new
View.OnClickListener() {
@Override
public void onClick(View v) {
Assinador assinador = new Assinador(pathPKCS12, senha, aliasCertificado, pathDocumento,senhaAlias);
assinador.atualizar(pathAssinatura);
boolean assinou = assinador.verificar();
if(assinou){
Toast.makeText(TelaVerificaAssinatura.this, "Assinatura Verifica com Sucesso!", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(TelaVerificaAssinatura.this, "Falha na Verificao", Toast.LENGTH_SHORT).show();
}
}
});
}
@Override
protected void onActivityResult(int codigo, int resultado,Intent it) {
if (codigo == ESCOLHA) {
if(it != null){
Bundle params =
it.getExtras();

if (params != null) {

if(params.getString("tipo").equals("certificado")){
pathPKCS12 = params.getString("path");
if(pathPKCS12.endsWith("p12")||pathPKCS12.endsWith("pfx")){
Intent intent = new In-

64
tent(TelaVerificaAssinatura.this,TelaSolicitarSenhaPKCS12.class);
intent.putExtra("tipo", "obterSenha");
intent.putExtra("path", pathPKCS12);
startActivityForResult(intent, ESCOLHA);
Log.i(CATEGORIA, " pathPKCS12 = "+pathPKCS12);
}
}
if(params.getString("tipo").equals("assinatura")){
pathAssinatura = params.getString("path");
}
if(params.getString("tipo").equals("escolherDocumento")){
pathDocumento = params.getString("path");
}
if(params.getString("tipo").equals("aliasCertificado")){
aliasCertificado = params.getString("alias");
}
if(params.getString("tipo").equals("obterSenha")){
senha =
params.getString("senha");

Intent
nova = new Intent(TelaVerificaAssinatura.this,TelaLeituraPKCS12.class);
nova.putExtra("path", pathPKCS12);
nova.putExtra("tipo", "aliasCertificado");
nova.putExtra("senha", senha);
startActivityForResult(nova,ESCOLHA);
}
}
}
}
}

65

TelaLeituraPKCS12.java

package br.cederj.tcc.activity;
import
import
import
import

java.security.KeyStore;
java.util.ArrayList;
java.util.Enumeration;
java.util.List;

import
import
import
import
import
import
import
import
import
import
import
import
import

android.app.Activity;
android.content.Intent;
android.os.Bundle;
android.util.Log;
android.view.View;
android.widget.AdapterView;
android.widget.AdapterView.OnItemSelectedListener;
android.widget.ArrayAdapter;
android.widget.Button;
android.widget.Spinner;
android.widget.Toast;
br.cederj.tcc.R;
br.cederj.tcc.ferramentas.Ferramentas;

/**
* @author Sidney Loyola de S
* @version 1.0
* Aplicativo desenvolvido para o
* Trabalho de Concluso de Curso submetido ao
* Curso de Tecnologia em Sistemas de Computao da
* Universidade Federal Fluminense
* como requisito parcial para obteno do ttulo de
* Tecnlogo em Sistemas de Computao
*
*/
public class TelaLeituraPKCS12 extends Activity implements OnItemSelectedListener{
String CATEGORIA = "ASSINADOR 1.6";
String alias = "";
@Override
protected void onCreate(Bundle savedInstanceState) {

66

super.onCreate(savedInstanceState);
setContentView(R.layout.tela_leitura_pkcs12);
Intent it = getIntent();
final String path = it.getExtras().getString("path");
final String tipo = it.getExtras().getString("tipo");
final String senha =
it.getExtras().getString("senha");
Log.i(CATEGORIA, "PATH 2 : "+path);
KeyStore store;
try {
store = KeyStore.getInstance("PKCS12",
"BC");
char[] password = senha.toCharArray();
store.load(Ferramentas.ler(path), password);
List<String>listaAlias = new ArrayList<String>();
Enumeration en = store.aliases();
while (en.hasMoreElements())
{
String alias = (String)en.nextElement();
if(store.isKeyEntry(alias)){
Log.i(CATEGORIA, "Alias : "+alias);
listaAlias.add(alias);
}
}
String[]arrayAlias = transformar(listaAlias);
Log.i(CATEGORIA, "Alias [0] : "+arrayAlias[0]);

Spinner spinner = (Spinner)


findViewById(R.id.spinnerAlias);
ArrayAdapter<String> adaptador = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item,arrayAlias);
adaptador.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_it
em);
spinner.setAdapter(adaptador);
spinner.setOnItemSelectedListener(this);
Button botaoSalvar = (Button) findViewById(R.id.botaoSalvarCertificado);
botaoSalvar.setOnClickListener(new
View.OnClickListener() {

67

@Override
public void onClick(View v) {
Intent itNova = new Intent();
itNova.putExtra("path",path);
itNova.putExtra("tipo",tipo);
itNova.putExtra("senha",senha);
itNova.putExtra("alias",alias);
setResult(1, itNova);
finish();
}
});

} catch (Exception e) {
e.printStackTrace();
}

}
public void onItemSelected(AdapterView<?> parent, View view,
int pos, long id) {
alias = (String) parent.getItemAtPosition(pos);
Toast.makeText(this, "Alias: "+alias,
Toast.LENGTH_SHORT).show();
}
public void onNothingSelected(AdapterView<?> parent) {
alias = (String) parent.getItemAtPosition(0);
Toast.makeText(this, "Alias: "+alias,
Toast.LENGTH_SHORT).show();
}
private String[] transformar(List<String> listaAlias) {

68
String[]array = new String[listaAlias.size()];
for(int i=0;i<listaAlias.size();i++){
array[i] = listaAlias.get(i);
}
return array;
}
}

TelaSelecionarSenhaChavePrivada.java

package br.cederj.tcc.activity;
import java.security.KeyStore;
import java.security.PrivateKey;
import
import
import
import
import
import
import
import
import

br.cederj.tcc.R;
android.app.Activity;
android.content.Intent;
android.os.Bundle;
android.view.View;
android.widget.Button;
android.widget.EditText;
android.widget.TextView;
android.widget.Toast;

/**
* @author Sidney Loyola de S
* @version 1.0
* Aplicativo desenvolvido para o
* Trabalho de Concluso de Curso submetido ao
* Curso de Tecnologia em Sistemas de Computao da
* Universidade Federal Fluminense
* como requisito parcial para obteno do ttulo de
* Tecnlogo em Sistemas de Computao
*
*/
public class TelaSelecionarSenhaChavePrivada extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tela_obter_senha);

69
TextView titulo = (TextView) findViewById(R.id.titulo);
titulo.setText("Digite a Senha :");
final EditText campoSenha = (EditText) findViewById(R.id.campoSenha);
Button botaoSalvar = (Button) findViewById(R.id.botaoSalvarSenha);
botaoSalvar.setOnClickListener(new
View.OnClickListener() {
@Override
public void onClick(View v) {
Intent it = getIntent();
String tipo =
it.getExtras().getString("tipo");
String path =
it.getExtras().getString("path");
String senhaPKCS12 =
it.getExtras().getString("senha");
String alias =
it.getExtras().getString("alias");
String senhaAlias = campoSenha.getText().toString();
boolean senhaCorreta = true;
KeyStore store;
try {
store = KeyStore.getInstance("PKCS12", "BC");
char[] password =
senhaPKCS12.toCharArray();
store.load(br.cederj.tcc.ferramentas.Ferramentas.ler(path), password);
PrivateKey chave = (PrivateKey) store.getKey(alias, password);
}catch (Exception e) {
senhaCorreta =
false;
}
if(senhaCorreta){
Intent senha = new Intent();
senha.putExtra("tipo", tipo);
senha.putExtra("senhaAlias", senhaAlias);
setResult(1, senha);

70
finish();
}else{
Toast.makeText(TelaSelecionarSenhaChavePrivada.this, "Senha Incorreta",
Toast.LENGTH_SHORT).show();
}
}
});
}
}

TelaSolicitarSenhaPKCS12.java

package br.cederj.tcc.activity;
import java.security.KeyStore;
import br.cederj.tcc.R;
import
import
import
import
import
import
import

android.app.Activity;
android.content.Intent;
android.os.Bundle;
android.view.View;
android.widget.Button;
android.widget.EditText;
android.widget.Toast;

/**
* @author Sidney Loyola de S
* @version 1.0
* Aplicativo desenvolvido para o
* Trabalho de Concluso de Curso submetido ao
* Curso de Tecnologia em Sistemas de Computao da
* Universidade Federal Fluminense
* como requisito parcial para obteno do ttulo de
* Tecnlogo em Sistemas de Computao
*
*/
public class TelaSolicitarSenhaPKCS12 extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

71
setContentView(R.layout.tela_obter_senha);
final EditText campoSenha = (EditText) findViewById(R.id.campoSenha);
Button botaoSalvar = (Button) findViewById(R.id.botaoSalvarSenha);
botaoSalvar.setOnClickListener(new
View.OnClickListener() {
@Override
public void onClick(View v) {
Intent it = getIntent();
String tipo =
it.getExtras().getString("tipo");
String path =
it.getExtras().getString("path");
String senhaPKCS12 = campoSenha.getText().toString();
boolean senhaCorreta = true;
KeyStore store;
try {
store = KeyStore.getInstance("PKCS12", "BC");
char[] password =
senhaPKCS12.toCharArray();
store.load(br.cederj.tcc.ferramentas.Ferramentas.ler(path), password);
}catch (Exception e) {
senhaCorreta =
false;
}
if(senhaCorreta){
Intent senha = new Intent();
senha.putExtra("senha",
senhaPKCS12);
senha.putExtra("tipo",tipo);
senha.putExtra("path",
path);
setResult(1, senha);
finish();
}else{
Toast.makeText(TelaSolicitarSenhaPKCS12.this, "Senha Incorreta", Toast.LENGTH_SHORT).show();
}

72

}
});
}

Assinador.java

package br.cederj.tcc.assinador;
import
import
import
import
import

java.io.File;
java.security.KeyStore;
java.security.PrivateKey;
java.security.Signature;
java.security.cert.Certificate;

import br.cederj.tcc.ferramentas.Ferramentas;

/**
* @author Sidney Loyola de S
* @version 1.0
* Aplicativo desenvolvido para o
* Trabalho de Concluso de Curso submetido ao
* Curso de Tecnologia em Sistemas de Computao da
* Universidade Federal Fluminense
* como requisito parcial para obteno do ttulo de
* Tecnlogo em Sistemas de Computao
*
*/
public class Assinador {
private String path;
private char[]password ;
private String alias;
private String pathDocumento;
private String pathAssinatura;
private String senhaAlias;
private
private
private
private

byte[] message;
byte[] assinatura;
PrivateKey chave;
Certificate cert;

73
public Assinador(String path,String senha,String alias,String
pathDocumento,String senhaAlias){
this.path = path;
this.password = senha.toCharArray();
this.alias = alias;
this.pathDocumento = pathDocumento;
this.senhaAlias = senhaAlias;
}
private void configurar() {
try {
message = Ferramentas.getBytesFromFile(new
File(pathDocumento));
KeyStore store = KeyStore.getInstance("PKCS12", "BC");
store.load(Ferramentas.ler(path), password);
chave = (PrivateKey) store.getKey(alias, senhaAlias.toCharArray());
} catch (Exception e) {
}
}
public boolean assinar() throws Exception, Exception{
configurar();
Signature signer = Signature.getInstance("Sha1WithRSA", "BC");
signer.initSign(chave);
signer.update(message);

byte[]assinatura = signer.sign();
Ferramentas.escrever(assinatura, pathDocumento +
".p7s");
return true;
}
public void atualizar(String pathAssinatura) {
this.pathAssinatura = pathAssinatura;
}
public boolean verificar() {

74
configurarVerificacao();
try {
Signature signer = Signature.getInstance("Sha1WithRSA", "BC");
signer.initVerify(cert);
signer.update(message);
return signer.verify(assinatura);
} catch (Exception e) {
return false;
}
}
private void configurarVerificacao() {
cert = null;
try {
KeyStore store = KeyStore.getInstance("PKCS12", "BC");
store.load(Ferramentas.ler(path), password);
Certificate[] chain =
store.getCertificateChain(alias);
cert = chain[0];
message = Ferramentas.getBytesFromFile(new
File(pathDocumento));
assinatura = Ferramentas.getBytesFromFile(new File(pathAssinatura));
} catch (Exception e) {
}
}
}

Ferramentas.java

package br.cederj.tcc.ferramentas;

75
import
import
import
import
import
import
import

java.io.BufferedOutputStream;
java.io.File;
java.io.FileInputStream;
java.io.FileNotFoundException;
java.io.FileOutputStream;
java.io.IOException;
java.io.InputStream;

/**
* @author Sidney Loyola de S
* @version 1.0
* Aplicativo desenvolvido para o
* Trabalho de Concluso de Curso submetido ao
* Curso de Tecnologia em Sistemas de Computao da
* Universidade Federal Fluminense
* como requisito parcial para obteno do ttulo de
* Tecnlogo em Sistemas de Computao
*
*/
public class Ferramentas {
public static InputStream ler(String path){
try {
File file = new File(path);
InputStream is = new FileInputStream(file);
return is;
} catch (FileNotFoundException ex) {
}
return null;
}
public static byte[] getBytesFromFile(File file) throws IOException {
InputStream is = new FileInputStream(file);
long length = file.length();
if (length > Integer.MAX_VALUE) {
}
byte[] bytes = new byte[(int)length];
int offset = 0;
int numRead = 0;

76
while (offset < bytes.length
&& (numRead=is.read(bytes, offset, bytes.lengthoffset)) >= 0) {
offset += numRead;
}
if (offset < bytes.length) {
throw new IOException("Could not completely read file
"+file.getName());
}
is.close();
return bytes;
}
public static void escrever(byte[] bytes,String path){
try {
File file = new File(path);
BufferedOutputStream bos;
bos = new BufferedOutputStream(new
FileOutputStream(file));
bos.write(bytes);
bos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
}

FileArrayAdapter.java

package cederj.tcc.FileChooser;
import java.util.List;

77

import
import
import
import
import
import
import

android.content.Context;
android.view.LayoutInflater;
android.view.View;
android.view.ViewGroup;
android.widget.ArrayAdapter;
android.widget.TextView;
br.cederj.tcc.R;

public class FileArrayAdapter extends ArrayAdapter<Option>{


private Context c;
private int id;
private List<Option>items;

public FileArrayAdapter(Context context, int textViewResourceId,List<Option> objects) {


super(context, textViewResourceId, objects);
c = context;
id = textViewResourceId;
items = objects;

}
public Option getItem(int i)
{
return items.get(i);
}
@Override
public View getView(int position, View convertView, ViewGroup
parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(id, null);

78

}
final Option o = items.get(position);
if (o != null) {
TextView t1 = (TextView) v.findViewById(R.id.TextView01);
TextView t2 = (TextView) v.findViewById(R.id.TextView02);
if(t1!=null)
t1.setText(o.getName());
if(t2!=null)
t2.setText(o.getData());
}
return v;
}

FileChooser.java

package cederj.tcc.FileChooser;
import
import
import
import

java.io.File;
java.util.ArrayList;
java.util.Collections;
java.util.List;

import
import
import
import
import
import
import

android.app.ListActivity;
android.content.Intent;
android.os.Bundle;
android.view.View;
android.widget.ListView;
android.widget.Toast;
br.cederj.tcc.R;

public class FileChooser extends ListActivity {


/** Called when the activity is first created. */
private File currentDir;
FileArrayAdapter adapter;

79

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
currentDir = new File("/sdcard/"); //adaptao para
abrir o carto de memria
fill(currentDir);
}
private void fill(File f) {
File[] dirs = f.listFiles();
this.setTitle("Current Dir: " + f.getName());
List<Option> dir = new ArrayList<Option>();
List<Option> fls = new ArrayList<Option>();
try {
for (File ff : dirs)
{
if (ff.isDirectory())
dir.add(new Option(ff.getName(), "Folder", ff
.getAbsolutePath()));
else
{
fls.add(new Option(ff.getName(), "File Size: "
+
ff.length(), ff.getAbsolutePath()));
}
}
} catch (Exception e) {
}
Collections.sort(dir);
Collections.sort(fls);

80
dir.addAll(fls);
if (!f.getName().equalsIgnoreCase("sdcard"))
dir.add(0, new Option("..", "Parent Directory", f.getParent()));
adapter = new FileArrayAdapter(FileChooser.this,R.layout.file_view,dir);
this.setListAdapter(adapter);
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Option o = adapter.getItem(position);
if(o.getData().equalsIgnoreCase("folder")||o.getData().equalsIgnoreCase
("parent directory")){
currentDir = new File(o.getPath());
fill(currentDir);
}else
{
onFileClick(o);
}
}
// este metodo foi adaptado para que a intent gerasse o retorno desejado
private void onFileClick(Option o)
{
Intent it = getIntent();
String tipo = it.getExtras().getString("tipo");
Intent nova = new Intent();
//Seta a mensagem de retorno
nova.putExtra("path",o.getPath());
nova.putExtra("name", o.getName());
nova.putExtra("tipo", tipo);
setResult(1,nova);

81

//Fim desta activity


finish();
}
}

Option.java

package cederj.tcc.FileChooser;
public class Option implements Comparable<Option> {
private String name;
private String data;
private String path;
public Option(String n, String d, String p)
{
name = n;
data = d;
path = p;
}
public String getName()
{
return name;
}
public String getData()
{
return data;
}
public String getPath()

82

{
return path;
}
@Override
public int compareTo(Option o) {
if(this.name != null)
return
this.name.toLowerCase().compareTo(o.getName().toLowerCase());
else
throw new IllegalArgumentException();
}
}

tela_inicial.xml

<?xml version="1.0" encoding="utf8"?>


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<Button
android:id="@+id/botaoAssinar"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="50dp"
android:text="@string/assinarDocumento" />
<Button
android:id="@+id/botaoVerificar"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/verificarAssinatura" />
<Button
android:id="@+id/button4"
android:layout_width="250dp"
android:layout_height="wrap_content"

83
android:layout_gravity="center"
android:text="@string/sobre" />
</LinearLayout>

tela_assina_documento.xml
<?xml version="1.0" encoding="utf8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/espaco"
android:textAppearance="?android:attr/textAppearanceLarge" />
<Button
android:id="@+id/botao_escolher_chave"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="50dp"
android:text="@string/escolher_chave_privada" />
<Button
android:id="@+id/botaoEscolherDocumento"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="@string/escolher_documento" />
<Button
android:id="@+id/botaoAssinarDocumento"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="@string/assinarDocumento" />
</LinearLayout>

tela_verifica_assinatura.xml
<?xml version="1.0" encoding="utf8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"

84
android:orientation="vertical" >
<Button
android:id="@+id/botaoEscolherAssinatura"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="50dp"
android:text="@string/escolher_assinatura" />
<Button
android:id="@+id/botaoEscolherCertificado"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="@string/escolher_certificado" />
<Button
android:id="@+id/botaoEscolherDocumentoOriginal"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="@string/escolher_documento" />
<Button
android:id="@+id/botaoVerificaAssinatura"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="@string/verificarAssinatura" />
</LinearLayout>

tela_leitura_pkcs12.xml
<?xml version="1.0" encoding="utf8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/certificados"
android:textAppearance="?android:attr/textAppearanceLarge" />
<Spinner
android:id="@+id/spinnerAlias"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<! Preview: listitem=@android:layout/simple_spinner_item >
</Spinner>
<Button
android:id="@+id/botaoSalvarCertificado"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="@string/salvar" />
</LinearLayout>

tela_obter_senha.xml

85
<?xml version="1.0" encoding="utf8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/titulo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/senha"
android:textAppearance="?android:attr/textAppearanceLarge" />
<EditText
android:id="@+id/campoSenha"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPassword" >
<requestFocus />
</EditText>
<Button
android:id="@+id/botaoSalvarSenha"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="@string/salvar" />
</LinearLayout>

file_view.xml
<?xml version="1.0" encoding="utf8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content" android:orientation="vertical"
android:layout_width="fill_parent">
<TextView android:text="@+id/TextView01" android:id="@+id/TextView01"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:singleLine="true" android:textStyle="bold" android:layout_marginTop="5dip"
android:layout_marginLeft="5dip"></TextView>
<TextView android:text="@+id/TextView02" android:id="@+id/TextView02"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="10dip"></TextView>
</LinearLayout>

86

AndroidManifest.xml
<?xml version="1.0" encoding="utf8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="br.cederj.tcc"
android:versionCode="1"
android:versionName="1.0" >
<usessdk android:minSdkVersion="8" />
<usespermission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<usespermission android:name="android.permission.INSTALL_PACKAGES"/>
<application
android:icon="@drawable/img_cadeado"
android:label="@string/app_name" >
<activity
android:name=".activity.TelaInicial"
android:label="@string/app_name" >
<intentfilter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intentfilter>
</activity>
<useslibrary android:required="true" android:name="android.test.runner"/>
<activity android:name=".activity.TelaAssinaDocumento"></activity>
<activity android:name="cederj.tcc.FileChooser.FileChooser"></activity>
<activity android:name=".activity.TelaSolicitarSenhaPKCS12"></activity>
<activity android:name=".activity.TelaLeituraPKCS12"></activity>
<activity android:name=".activity.TelaVerificaAssinatura"></activity>
<activity android:name=".activity.TelaSelecionarSenhaChavePrivada"></activity>
</application>
</manifest>

Das könnte Ihnen auch gefallen