quinta-feira, fevereiro 16, 2006

Assinatura de Applets :: Java Free.org

Introdução
O modelo de segurança implementado pela plataforma Java, na sua proposição inicial, é centrada sobro o conceito de sandbox (caixa de areia) (4). De acordo com o modelo sandbox, um código remoto (applet) não é confiável e pode acessar recursos limitados, fornecidos dentro do sandbox, uma área do Servidor Web dedicado àquele applet. A idéia de sandbox foi desenvolvida no sentido de garantir que mesmo que um usuário carregue um applet malicioso, esse não pode danificar a máquina local, por exemplo, apagar um arquivo do seu disco local.

Porém existem applets que são de confiança e necessitam s air do sandbox para fornecer um determinado serviço. Existem varias maneiras para resolver este problema, uma delas é a assinatura do applet. (4)

O JDK 1.1.x introduziu o conceito de applet assinado. Neste modelo estendido, um applet assinado digitalmente é tratado como código local confiável (aplicação standalone) se a assinatura é reconhecida como confiável pelo sistema que recebeu o applet. Entretanto no JDK 1.2.x, o applet assinado terá liberdades conforme especificado por um arquivo de política (policy file). Utilizou-se neste trabalho para o processo de assinatura e verificação do Applet Cliente a versão JDK 1.2.1.

Assinatura digital é utilizada quando se necessita da certeza da origem de uma mensagem como se fosse uma assinatura escrita no papel. Para assinar um applet, o desenvolvedor empacota todo o código Java e arquivos relacionados dentro de um arquivo JAR (Java ARchive) (2), que é um formato de arquivo de compactação de propósito geral, usado para compactar os componentes de uma aplicação Java. A plataforma Java assina e verifica arquivos JAR usando um par de chaves (chave pública e chave privada). A chave privada funciona como uma "caneta" eletrônica que assina o arquivo (ver Figura 1). Como o próprio nome sugere, esta chave só é conhecida pelo assinante do applet. O processo de verificação da assinatura pode ser feito por qualquer pessoa que possua a chave pública correspondente a chave que assinou o arquivo.(1)


0

[size=9:1f763170b3]Figura 1 ? Processo de assinatura[/size:1f763170b3]


A chave pública é distribuída dentro de um certificado que é uma declaração assinada por uma entidade idônea, chamada Autoridade de Certificação (Certification Authority- CA), que confirma que a chave pública que está no mesmo é confiável. Existem várias Autoridades de Certificação, por exemplo, a VeriSign, Thawte, Entrust e Certisign (empresa brasileira). Toda CA requer um emissor para validar a sua identidade, até mesmo a de mais alto nível. Para estes casos, existem os certificados auto-assinados (self-signed), onde o emissor do certificado é o próprio sujeito.

Os browsers Netscape e Internet Explorer (IE) não usam a codificação de assinatura do JDK. Existem basicamente três tipos diferentes de assinatura de applets, para o IE, para o Netscape, e para o plug-in Java da Sun. Este último fornece aos browsers citados acima a capacidade de utilizar applets assinados através da Java Security API do kit JDK.

Algumas ferramentas necessárias para a assinatura, seguindo o padrão da Sun, encontram-se no JDK 1.2, são elas (7):

Jar (JAR Creation Tool)
Keytool (Key and Certificate Management Tool)
Jarsigner (JAR Signing and Verification Tool)
PolicyTool (Policy File Creation and Management Tool)
Para uma melhor compreensão, encontra-se descritos a seguir os passos utilizados no processo de assinatura e verificação do AppletClient.

Passos para assinar um Applet
Os passos para assinar um Applet estão representados na Figura 2:

0
[size=9:1f763170b3]Figura 2 ? Diagrama de blocos do processo de assinatura por parte do desenvolvedor [/size:1f763170b3]

Criar o arquivo JAR (2)Deve-se criar um arquivo JAR contendo o arquivo .class da Applet e todas as classes que serão utilizadas e que farão uso de recursos fora do sandbox conforme indicado no item 1 da Figura 2. É importante ressaltar que a ferramenta jarsigner somente assinará arquivos JAR criados pelo JDK, ou arquivos ZIP.

Uma ferramenta utilizada para criação deste arquivo é o jar do JDK. Para criar um JAR contendo o arquivo MeuApplet.class, com o nome MeuJar.jar basta fazer:

Quote:
jar cvf MeuJar.jar MeuApplet.class  


Utilizou-se a opção "exportar para arquivo JAR" do Visual Age (ambiente de desenvolvimento Java da IBM) para empacotar os arquivos necessários.

Gerar o par de chaves (pública e privada) (5)

Este passo deve ser executado se ainda não houver um par de chaves a ser usado no processo de assinatura (ver item 2 da Figura 2). Para criar o par de chaves utiliza-se a ferramenta keytool do JDK cujas opções são:

Quote:
Keytool -genkey {-alias alias} {-keyalg keyalg} {-keysize keysize} {-sigalg sigalg} {-dname dname} {-keypass keypass} {-validity valDays} {-storetype storetype} {-keystore keystore} {-storepass storepass} {-v} {-Jjavaoption}  


Quote:
alias þ Nome pelo qual as chaves serão reconhecidas e armazenadas no keystore (banco de chaves). Ex: mykey
keyalg þAlgoritmo de criptografia utilizado para a criação das chaves. Este argumento é opcional, se nada for especificado o algoritmo utilizado será o DSA (Digital Signature Algorithm). Neste projeto foi utilizada esta opção default.
keysize þ Tamanho da chave que será gerada. O algoritmo DSA suporta tamanhos de 512 a 1024 bits, sendo o tamanho necessariamente múltiplo de 64. Para qualquer algoritmo o tamanho default é 1024.
sigalg þAlgoritmo de criptografia utilizado para assinar o JAR. Este argumento é opcional, se nada for especificado o algoritmo utilizado será o DSA.
dname þ Nome da entidade que gerará o par de chaves Ex:
CN=Banco do DAS, OU=LCMI, O=UFSC, L=Florianópolis, S=Santa Catarina, C=BR
Onde : CN = nome comum, OU = unidade organizacional (departamento, divisão), O = nome da organização, L = nome da localidade (cidade), S = estado, C = código do país.
keypass þ Senha utilizada para a proteção da chave no keystore.
validity þ Número de dias que o certificado deve ser válido.
storetype þ Permite definir a forma de armazenamento e o formato dos dados do keystore. Por default o formato é JKS (tipo proprietário da implementação de keystore fornecido pela Sun).
keystore þkeystore onde as chaves serão armazenadas. Se nada for especificado serão armazenadas no User.Home\.keystore (em geral c:\windows\.keystore), se não existir este será criado.
storepass þ Senha protetora do keystore.
v þ Mostra o certificado em forma legível  

Para a criação das chaves empregadas neste projeto utilizou-se a seguinte linha de comando:

Quote:
keytool -genkey -dname "cn=Banco do Das, ou=LCMI, o=UFSC, c=BR" -alias key -keystore u:\grupo\mykeystore -storepass 123456 -validity 180  

Quando as chaves são geradas (comando ?genkey) um certificado auto-assinado é criado. Caso deseje-se trocar este certificado por um certificado reconhecido por uma empresa confiável, deve-se fazer um pedido de certificado de assinatura (CSR CerticateSigning Request), e o resultado desta solicitação deve ser importado para o keystore.

Assinar o arquivo JAR (4)

Deve-se assinar o arquivo JAR com a chave privada, para isto utiliza-se a ferramenta jarsigner do JDK, conforme esquematizado no item 3 da Figura 2, da seguinte forma:

Quote:
jarsigner [options] jar-file alias  


Onde o jar-file é o arquivo a ser assinado, e o alias, é o nome com o qual a chave privada foi guardada no keystore. As opções são as seguintes:

Quote:
jarsigner {-keystore url} {-storetype storetype} {-storepass storepass} {-keypass keypass} {-sigfile sigfile} {-signedjar signedjar} {-verbose} {-Jjavaoption}  


keystore þ URL do keystore onde a chave está armazenada. Se nada for especificado serão armazenadas no User.Home\.keystore (em geral c:\windows\.keystore).
storetype þ especifica o tipo do keystore que será instanciado. O tipo default do keystore é especificado pelo valor da propriedade de "keystore.type", no arquivo de propriedades de segurança.
storepass þSenha protetora do keystore. Se não for informada, o programa perguntará antes de assinar.
keypass þ Senha protetora da chave privada. Se não for informada, o programa perguntará antes de assinar.
sigfile þ Especifica o nome a ser usado nos arquivos .SF (arquivo de assinatura) e .DSA (bloco de assinatura).Se nada for especificado, o nome será os 8 primeiros caracteres do alias especificado, se o alias tiver menos que 8, seu nome inteiro será colocado.
signedjar þ Especifica o nome e o local de armazenamento do arquivo JAR assinado. Por default, o arquivo assinado irá sobrescrever o não assinado.
verbose þ Indica o modo verbose, que faz aparecer mais informações na tela durante o processo de assinatura.
A linha de comando utilizada neste projeto foi:

Quote:
jarsigner -keystore u:\grupo\mykeystore -storepass 123456 -signedjar asistemaBancario.jar sistemaBancario.jar key  


Exportar o Certificado da chave pública (5)

Para que se possa distribuir a chave pública é necessário um certificado autenticando a mesma, deve-se exportar o certificado que está no keystore usando a ferramenta keytool do JDK (ver item 4 Figura 2).

Quote:
keytool -export {-alias alias} {-file cert_file} {-storetype storetype} {-keystore keystore} {-storepass storepass} {-rfc} {-v} {Jjavaoption}  


Quote:
alias þ Nome com o qual a chave foi guardada no keystore.
file þLocal e nome com o qual o certificado será exportado.
storetype þ Especifica o tipo do keystore que será instanciado. O tipo default do keystore é especificado pelo valor da propriedade de "keystore.type", no arquivo de propriedades de segurança.
keystore þ Local do keystore onde o certificado está armazenado. Se nada for especificado serão exportadas do User.Home\.keystore (em geral c:\windows\.keystore).
storepass þSenha protetora do keystore. Se não for informada o programa perguntará antes de exportar.
rfc þ Exporta o certificado na forma definida pelo padrão Internet RFC 1421. Quando exportado desta forma este começa com"-------Begin" e termina por "------End".
v þ Indica o modo verbose, que faz aparecer mais informações na tela enquanto exporta o certificado.  


Neste projeto utilizou-se a seguinte linha de comando:

Quote:
keytool -export -keystore u:\grupo\mykeystore -alias key -file keycert.x509  

O certificado exportado deve ser enviado para os usuários do applet.

Criar a página HTML ( 8 )

Conforme demonstrado no item 5 da Figura 2, para o Applet funcionar nos browser Netscape e IE, é necessário instalar o Plug-in, fornecido pela Sun, e converter a página HTML para que esta informe qual JVM (Java Virtual Machine) será utilizada.

Para fazer a página com suporte a Plug-in basta utilizar a ferramenta HTMLConverter também fornecida pela Sun. Porém, é necessário que uma página previamente pronta, contenha a informação de que um arquivo assinado será utilizado. A Tag deve ser:

Quote:
<applet quote="Applet.class" ARCHIVE="arquivoAssinado.jar" wdth=500 height=50>
</applet>  

Note que isto é apenas a Tag do applet, a página HTML pode conter outros dados.

Se o applet for rodar no appletviewer, não é preciso converter a página pois o plug-in só é necessário nos browsers.

Passos para verificar a assinatura
Os passos que o usuário deve seguir estão representados na Figura 3:

0

Instalar Plug-in ( 8 )
Para que o Applet funcione é indispensável que o usuário instale em seu browser a ultima versão do Java Plug-in, fornecido pela Sun (ver item 1 da Figura 3).

Importar o Certificado (5)
Segundo apresentado no item 2 da Fifura 3, o usuário deve importar o certificado enviado pelo desenvolvedor do applet para um keystore de seu disco local, utilizando a ferramenta keytool do JDK.

Quote:
keytool -import {-alias alias} {-file file}  


Quote:
alias þ nome com o qual o certificado será importado.
file þ local e nome do certificado.  


Este passo pode ser facilitado pelo desenvolvedor da aplicação se este fornecer o arquivo .keystore, sendo apenas necessário gravá-lo no user.home. Porém, se o usuário deseja ter outros certificados além do fornecido pelo desenvolvedor, este terá que importá-lo, não esquecendo de informar que ele é trusted quando a ferramenta keytool perguntar.

Configurar o Arquivo Policy
Como último passo (ver item 3 Figura 3), tem-se a configuração do arquivo de política no disco local do usuário da aplicação. Este arquivo informa quais permissões serão atribuídas para as aplicações especificadas. O arquivo policy, pode ser escrito em um arquivo de texto normal, pode ser gerado utilizando a ferramenta policytool do JDK1.2.x., ou ainda pode ser fornecido pelo desenvolvedor da aplicação.

Quando fornecido pelo desenvolvedor, o arquivo policy conterá apenas as permissões da aplicação e deverá ser gravado no user.home\.java.policy. Caso o usuário deseje definir permissões para outras aplicações, este deverá configurá-las no seu arquivo policy.

Neste trabalho utilizou-se a ferramenta policytool, onde o desenvolvedor definiu as permissões necessária para o AppletClient se conectar ao Serviço de Nomes e ao Servidor Bancário e forneceu o arquivo policy gerado ao usuário da aplicação.

Utilizando a Ferramenta policytool (6)
A Figura 4 apresenta a tela inicial do policytool, se estiver sendo usado pela primeira vez, este avisará que nenhum arquivo de política foi encontrado.

0
[size=9:1f763170b3]Figura 4 ? Tela inicial do aplicativo Policytool [/size:1f763170b3]


Para o usuário criar um novo arquivo, este deve ir no menu File e selecionar New, ou se quiser modificar um arquivo já existente, deve selecionar Open (no mesmo menu) e então escolher o arquivo.

Em seguida deve-se indicar qual keystore será usado. Selecionando o comando Change Keystore no menu Edit, a tela apresentada na Figura 5 solicitará a URL do local onde keystore está armazenado, por exemplo, file:/c:/windows/.keystore, e o tipo de arquivo deste keystore (não sendo necessário preencher, se o tipo for JKS-formato padrão da Sun). Terminada a operação pressiona-se o botão OK.

0
[size=9:1f763170b3]Figura 5 ? Tela de modificação do keystore do aplicativo Policytool[/size:1f763170b3]

Para adicionar as permissões que possibilitará ao Applet sair do sandbox, pressiona-se o botão Add Policy Entry (Figura 4). Surge então uma nova tela (ver Figura 6), solicitando o preenchimento do quoteBase com a URL do arquivo JAR assinado, se vários arquivos de uma pasta forem usados pode-se colocar um * ao invés do nome do arquivo JAR. E, o campo do SignedBy deve ser preenchido com o alias do certificado da chave que assinou o arquivo.

0
[size=9:1f763170b3]Figura 6 - Tela do aplicativo Policytool de apresentação das permissões concedidas ao applet[/size:1f763170b3]

Feitas estas operações, deve-se adicionar a permissão para o applet, pressionado o botão Add Permision da Figura 6. A tela da Figura 7 aparecerá, para que se escolha a permissão que será dada. Suponhamos que o Applet tenha que abrir uma conexão (Socket) com outra máquina, a permissão então será java.net.SocketPermission. No Target name pode-se permitir fazer um socket com qualquer outra máquina colocando um * ou especificar uma máquina. Em Actions deve-se escolher quais ações deseja-se permitir (connect, accept, resolve, listen).

0
[size=9:1f763170b3]Figura 7 - Tela para adicionar permissão do aplicativo Policytool[/size:1f763170b3]

Ao terminar pressiona-se o botão OK, depois Done (ver Figura 6), e salva-se o arquivo selecionando o menu File e depois Save (ver Figura 4).

Note que o Browser procurará pelo arquivo user.home\.java.policy para verificar as permissões de uma aplicação. Portanto, se o usuário do applet deseja que o arquivo policy criado seja utilizado, deve gravá-lo neste local.

Conclusões e Resultados
A implementação utilizando o plug-in Java da Sun demonstrou-se muito útil, pois pode ser utilizado nos browsers mais conhecidos, Netscape e Internet Explorer (IE) , ao passo que sem o plug-in, as assinaturas utilizando o Netscape ou Internet Explorer, por não usarem a codificação de assinatura do JDK, não são compatíveis resultando no não funcionamento do applet em ambos os browsers.

Em contrapartida, para que o processo seja concluído com sucesso, o usuário deve estar ciente que deve utilizar um arquivo policy e também possuir um keystore o que implica ter conhecimento sobre as ferramentas policytool, e keytool se desejar permitir acesso fora do sandbox para applets diferentes.

Demonstrado que esta forma de implementação de assinatura apresenta os resultados desejados, possibilitando todos os acessos necessários fora do sandbox.

Quote:
Bibliografia
(1) OAKS, Scott, Segurança de dados em JAVA, Editora Ciência Moderna Ltda, Rio de Janeiro, 1999.

(2) Sun Microsystems Inc., JAR Guide. Sun Microsystems Inc. Moutain View, CA.
( http://java.sun.com/products/jdk/1.2/docs/guide/jar/jarGuide.html )

(3) Sun Microsystems Inc., jarsigner ? JAR Signing and Verification Tool. Sun Microsystems Inc. Moutain View, CA, October 1998.
( http://java.sun.com/products/jdk/1.2/docs/tooldocs/win32/jarsigner.html

(4) Sun Microsystems Inc., Java Security Architecture (JDK1.2) Version 1.0. Sun Microsystems Inc. Moutain View, CA, October 1998.
( http://java.sun.com/products/jdk/1.2/docs/guide/security/spec/security-spec.doc.html )

(5) Sun Microsystems Inc., keytool - Key and Certificate Management Tool. Sun Microsystems Inc. Moutain View, CA, October 1998.
( http://java.sun.com/products/jdk/1.2/docs/tooldocs/win32/keytool.html )
(6) Sun Microsystems Inc.,Policy Tool - Policy File Creation and Management Tool. Sun Microsystems Inc. Moutain View, CA, October 1998.
Http://java.sun.com/products/jdk/1.2/docs/tooldocs/win32/policytool.html

(7) Sun Microsystems Inc., Summary of JDK 1.2 Security Tools. Sun Microsystems Inc. Moutain View, CA, October 1998.
( http://java.sun.com/products/jdk/1.2/docs/guide/security/SecurityToolsSummary.html )

( 8 ) Sun Microsystems Inc., JDK 1.2 - Signed Applet Example. Sun Microsystems Inc. Moutain View, CA, February 1999.
( http://java.sun.com/security/signExample12 )  



Luís Carlos Moreira
luis@javafree.com.br

Nenhum comentário: