Zona HTML Zona Java Zona PHP Zona ASP Zona Bases de datos
Inicio > Tutoriales > Lenguajes orientados a objeto > Java > J2SE > Seguridad en la Plataforma Java 2 JDK 1.2
-Tutoriales

Seguridad en la Plataforma Java 2 JDK 1.2


Fimar Código y Conceder Permisos

Esta lección ilustra el uso de las herramientas relacionadas con la seguridad (keytool, jarsigner, y Policy Tool). También mustra el suso de la herramienta jar para situar ficheros en un fichero JAR, para la posterior firma con la herramienta jarsigner.

En esta lección primero ejecutaremos los pasos para crear una aplicación, ponerla en un fichero JAR, firmar el fichero JAR, y exportar el certificado de la clave pública correspondiente a la clave privada usada para firmar el fichero JAR.

Luego actuaremos como el receptor del fichero JAR y del certificado. Veremos cómo la aplicación firmada, normalmente no puede leer un fichero cuando se ejecuta bajo un controlador de seguridad. Luego usaremos keytool para importar el certificado en nuestro keystore en una entrada con el alias susan, y Policy Tool para crear una entrada en el fichero de política de Ray para permitir que el código firmado por susan pueda leer el fichero especificado. Finalmente veremos como nuestra aplicación ejecutandose bajo un controlador se seguridad puede ahora leer el fichero, ya que se le ha concedido permiso para hacerlo.

Para más información osbre las firmas digitales, los certificados y las herramientas, puedes ver la lección anterior.

Nota Importante: Necesitamos hacer todo el trabajo de esta lección en el directorio en el que hayamos almacenado la aplicación de ejemplo, pero deberíamos almacenar lo ficheros de datos necesarios para la aplicación en un directorio diferente. Todos los ejemplos asumen que estamos trabajando en el directorio C:\Test, y que los ficheros de datos están el directorio C:\TestData.

. Pasos para el Firmante de Código

El firmante de código realiza los siguientes pasos que se muestran en la siguiente figura.

. Descargar y Probar la Aplicación de Ejemplo

La aplicación usada por esta lección está suministrada por tí.

Crea un fichero llamado Count.java en tu ordenador copiando o descargando el código fuente Count.java. Los ejemplos de esta lección asumen que lo has situado en el directorio C:\Test.

Ahora compilamos y ejecutamos la aplicación Count para ver qué hace. Necesitamos especificar (como argumento) el nombre y el path de un fichero a leer. Puedes descargar y utilizar este fichero de ejemplo llamado data.

Importante:  Para esta lección, pon el fichero de datos en otro directorio distinto al que contiene la aplicación Count. Los ejemplos asumen que has puesto el fichero de datos en el directorio C:\TestData. Más adelante en esta lección verás como una aplicación que se ejecuta bajo un controlador de seguridad no puede leer ficheros a menos que explicitamente se le de permiso para hacerlo. Sin embargo, una aplicación, siempre puede leer un fichero de su propio directoriro (o un subdirectorio); sin necesitar permiso explícito.

Un ejemplo de ejecución podría ser

    C:\Test>java Count C:\TestData\data
    Counted 65 chars.

. Crear un Fichero JAR que Contenga el Fichero Class

Para crear in fichero JAR que contenga el fichero Count.class. Debemos teclear lo siguiente en nuestra línea de comandos.

jar cvf Count.jar Count.class

Esto crea el fichero JAR, Count.jar, y situa el fichero Count.class dentro de él.

. Generar Claves

Si un firmante de código no tiene todavía una clave privada para firmar el código, primero debe generar la clave junto con una correspondiente clave pública que puede ser usada por el sistema de ejecución del receptor para verificar la firma.

Como esta lección asume que tu no tienes dichas claves, vas a crear un keystore llamado susanstore y ha crear una entrada con una pareja de claves pública/privada recien creada (con la clave pública en un certificado).

Ahora imaginemos que somos Susan Jones y que trabajamos en la departamento de ventas de la compañia ABC. Tecleamos el siguiente comando para crear el keystore llamado susanstore y para generar las claves para Susan Jones.

keytool -genkey -alias signFiles -keypass kpi135 
 -keystore susanstore -storepass ab987c

(Nota: Debe teclearse como una sóla línea.)

. Subpartes del Comando keytool

Echemos un vistazo a los que significan cada una de las subpartes de keytool.

  • El comando para generar claves es -genkey.
  • La subparte -alias signFiles indica el alias que se va usar en el futuro para referirse a la entrada del keystore que contiene las claves que se van a generar.
  • La subparte -keypass kpi135 especifica una password para la clave privada a generar. Esta password siempre en necesaria en caso de acceder a la entrada del keystore que contiene la clave. La entrada no tiene que tener su propia password ; si no incluimos una opción -keypass, se nos pedirá la password de la clave y nos ofrecerá la opción de permitir que sea la misma que la del keystore.
  • La subparte -keystore susanstore indica el nombre (y opcionalmente el path) del keystore que estamos creando o usando.
  • La subparte -storepass ab987c indica la password del keystore. Si no incluimos la opción -storepass, se nos pedirá la password para el keystore.

Por razones de seguridad no deberías realmente suministrar las password en la línea de comandos, porque podrían ser interceptadas fácilmente. en su lugar deberías desactivar las opciones -keypass y -storepass y teclear las password cuando te las pida.

. Información de Nombre-Distinguido

Si usamos el comando anterior, nos preguntará por la información del nombre-distinguido. En las siguientes preguntas, la parte en negrita indica lo que deberíamos responder.

What is your first and last name?
  [Unknown]:  Susan Jones 
What is the name of your organizational unit?
  [Unknown]:  Purchasing 
What is the name of your organization?
  [Unknown]:  ABC 
What is the name of your City or Locality?
  [Unknown]:  Cupertino 
What is the name of your State or Province?
  [Unknown]:  CA 
What is the two-letter country code for this unit?
  [Unknown]:  US 
Is <CN=Susan Jones, OU=Purchasing, O=ABC,
    L=Cupertino, ST=CA, C=US> correct?
  [no]:  y 

. Resultados del Comando

El comando keytool crea el keystore llamado susanstore (si no existía anteriormente) en el mismo directorio en que se ejecuta el comando y le asigna la password ab987c. El comando genera una pareja de claves pública/privada para la entidad cuyo nombre distinguido tiene un nombre común de Susan Jones y la unidad organizativa de Purchasing.

El comando crea un certificado auto-firmado que incluye la clave pública y la información del nombre distinguido. (El nombre distinguido que suministramos se usará en el campo "subject" en el certificado). Este certificado será válido durante 90 días, el periodo por defecto de validez si no especificamos una opción -validity. El certificado está asociado con la clave privada en una entrada del keystore referida por el alias signFiles. La clave privada tiene asignada la password kpi135.

Nota: El comando podría ser más corto si aceptamos las opciones por defecto y si deseamos que se nos pidan varios valores. Siempre que ejecutemos el comando keytool, se usan las opciones no específicadas que tengan valores por defecto, y se nos pedirá cualquier valor necesario. Para el comando genkey, las opciones con valores por defecto incluida el alias (cuyo valor por defecto es mykey), validity (90 dias), y keystore (el fichero llamado .keystore en nuestro directorio home). Los valores requeridos son dname, storepass, y keypass.

. Firmar el Fichero JAR

Ahora estamos listos para firmar el fichero JAR. Tecleando lo siguiente en la línea de comandos firmaremos el fichero JAR Count.jar, usando la clave privada en la entrada del keystore con el alias signFiles, y el nombre del fichero JAR firmado resultante será sCount.jar.

jarsigner -keystore susanstore -signedjar sCount.jar Count.jar signFiles 

Se nos pedirá la password del keystore (ab987c) y la password de la clave privada (kpi135).

Nota: La herramienta jarsigner extrae el certificado de la entrada del keystore cuyo alias es signFiles y lo adjunta a la firma generada para el fichero JAR firmado.

. Exportar el Certificado de la Clave Pública

Ahora tenemos un fichero JAR firmado sCount.jar. El sistema de ejecución del receptor del código necesitará autentificar la firma cuando la aplicación Count del fichero JAR firmado intente leer un fichero y un fichero de política le conceda el permiso para este código firmado.

Para permitir que el sistema de ejecución autentifique la firma, el keystore del receptor necesita tener la clave pública correspondiente a la clave privada usada para generar la firma. Podemos suministrarsela al receptor enviando una copia del certificado de autentificación de la clave pública. Copiamos este certificado desde el keystore susanstore a un fichero llamado SusanJones.cer de esta forma.

keytool -export -keystore susanstore -alias signFiles -file SusanJones.cer

Se nos pedirá la password del keystore (ab987c).

. Pasos para el Receptor del Código

Ahora actuaremos como Ray, que recibe el fichero JAR firmado y el fichero del certificado de Susan. Realizaremos los siguientes pasos, como se muestra en la figura.

. Observar las Restricciones de la Aplicación

La última parte de la lección Visión Rápida para Controlar Aplicaciones muestra cómo una aplicación puede ser ejecutada bajo un controlador de seguridad llamando al intérprete con el nuevo argumento de la línea de comando -Djava.security.manager. ¿Pero qué pasa si la aplicación reside dentro de un fichero JAR?

Una de las opciones del intérprete es la opción -cp (class path), con la que se especifica un path de búsqueda para las clases de la aplicación y los recursos. Así, por ejemplo, para ejecutar la aplicación Count dentro del fichero JAR sCount.jar, especificando el fichero C:\TestData\data como su argumento, podríamos teclear lo siguiente desde el directorio que contiene sCount.jar.

java -cp sCount.jar Count C:\TestData\data

Para ejecutar la aplicación con un controlador de seguridad, simplemente añadimos -Djava.security.manager, como en:

java -Djava.security.manager -cp sCount.jar Count C:\TestData\data

Cuando ejecutemos este comando, deberíamos obtener una excepción.

Exception in thread "main" java.security.AccessControlException.
access denied (java.io.FilePermission C:\TestData\data read)
    at java.security.AccessControlContext.checkPermission(Compiled Code)
    at java.security.AccessController.checkPermission(Compiled Code)
    at java.lang.SecurityManager.checkPermission(Compiled Code)
    at java.lang.SecurityManager.checkRead(Compiled Code)
    at java.io.FileInputStream.<init>(Compiled Code)
    at Count.main(Compiled Code)

Esta AccessControlException esta informando de que la aplicación no tiene permiso para leer el fichero C:\TestData\data. Esta excepción se lanza porque una aplicación que se está ejecutando bajo un controlador de seguridad no puede leer o esribir ficheros o acceder a otros recursos a menos que tenga permiso explícito para hacerlo.

. Importar el Certificado como un Certificado Verdadero

Antes de poder conceder permiso al código firmado para que lea un fichero específico, necesitamos importar el certificado de Susan como un certificado verdadero en nuestro keystore.

Supongamos que hemos recibido de Susan.

  • El fichero JAR sCount.jar, que contiene el fichero Count.class, y
  • el fichero SusanJones.cer, que contiene el certificado de clave pública para la clave pública correspondiente a la clave privada usada para firmar el fichero JAR.

Aunque acabemos de crear estos ficheros y realmente no han sido transportados desde ningún lugar, podemos simular que somos otra persona distinta al creador y emisor, Susan. Imaginemos que ahora somos Ray, crearemos un keystore llamado raystore y lo usaremos para importar dentro el certificado dentro de de una entrada con el alias de susan.

Un keystore se crea siempre que usemos un comando keytool especificando un keystore que no exista. Así podemos crear el raystore e importar el certificado mediante un solo comando keytool. Hacemos lo siguiente en nuestra línea de ocmandos.

  1. Vamos al directorio que contiene el fichero del certificado de la clave pública SusanJones.cer. (Ya deberíamos estar en él, ya que esta lección asume que estámos trabajando en un sólo directorio).
  2. Tecleamos el siguiente comando en una línea.
    keytool -import -alias susan
       -file SusanJones.cer -keystore raystore
    

Como el keystore no existe todavía, se creará, y nos pedirá que introduzcamos la password para el keystore, tecleamos cualquier password que queramos.

El comando keytool imprimirá la información del certificado y nos pedirá que lo verifiquemos, por ejemplo, comparando la huella dactilar del certificado mostrado con aquellas obtenidas de otra fuente de información (contrastada). (Cada huella dactilar es un número relativamente corto y único que identifica un certificado). Por ejemplo, en el mundo real podríamos llamar a Susan y preguntarle cual debería ser su huella dactilar. Ella puede obtener la huella del fichero SusanJones.cer.

keytool -printcert -file SusanJones.cer

Si las huellas dactilares corresponden, el certificado no ha sido modificado durante el tránsito. En este caso podemos permitir que keytool proceda con la inclusión de la entrada de certificado verdadero en el keystore. La entrada contiene los datos del certificado de la clave pública obtenidos del fichero SusanJones.cer y se le asigna el alias susan.

. Configurar un Fichero de Política para Conceder los Permisos Requeridos

Luego usaremos un la herramienta Policy Tool para crear un fichero de política llamando raypolicy y conceder un permiso para el código del fichero JAR firmado.

El fichero JAR debe haber sido firmado usando la clave privada correspondiente a la clave pública importada en el keystore de Ray (raystore) en los pasos anteriores. El certificado que contiene la clave pública tiene el alias de susan en el keystore. Concederemos a dicho código permiso para leer cualquier fichero del directorio C:\TestData\.

. Arrancar Policy Tool

Para arrancar Policy Tool, simplemente tecleamos esto en la línea de comandos.

policytool

Esto nos trae la ventana de Policy Tool. Siempre que se arranca, Policy Tool intenta rellenar su ventana con información de algo que algunas veces es referido como "fichero de política de usuario", que, por defecto, es un fichero llamado .java.policy que está en el directorio home. Si Policy Tool no puede encontrar ese fichero, informa de la situación y muestra una ventana Policy Tool en blanco (es decir, una ventana con cabeceras y botones pero sin datos, como se muestra en la figura.

Crearemos y trabajaremos sobre un fichero de política distinto del fichero de política de usuario, ya que las lecciones de esta sección no necesitan que se hagan modificaciones en el fichero de política de usuario oficial.

Asumiendo que estamos viendo una ventana de Policy Tool en blanco (si no es así, seleccionamos New en el menú File), podemos proceder inmediatamente a crear un nuevo fichero de política.

. Especificar el Keystore

Para esta lección concederemos permiso a todo el código en ficheros JAR firmados por el alias susan acceso de lectura a todos los ficheros en el directorio C:\TestData\. Necesitamos:

  1. Especificar el keystore que contiene la información del certificado con el alias susan.
  2. Crear la entrada de política que concede los permisos.

El keystore es uno llamado raystore creado en el paso "Importar el Certificado como un Certificado Verdadero".

Para especificar el keystore, elegimos el comando Change Keystore en el menú Edit en la ventana principal de Policy Tool. Esto nos muestra la caja de diálogo en que podemos especificar la URL del keystore especificado y el tipo de keystore.

Para especificar el keystore llamado raystore en el directorio Test del disco C:, tecleamos la siguiente URL en la caja de texto etiquetada New KeyStore URL.

file:/C:/Test/raystore

Podemos dejar en blanco la caja de texto etiquetada New KeyStore Type si el tipo de keystore es uno por defecto, como se especifica en fichero de propiedades de seguridad. Nuestro keystore será del tipo por defecto, por eso dejamos la caja de texto en blando. El resultado lo muestra la siguiente figura.

Nota: el valor de New KeyStore URL es una URL y por eso siempre se deben usar barras inclinadas (nunca barras inclinadas inversas), como separadores de directorio.

Cuando hayamos especificado la URL, elegios OK. La caja de texto etiquetada Keystore se rellena con la URL.

Luego, necesitamos especificar la nueva entrada de política.

. Añadir una Entrada de Política con un SignedBy Alias

Para conceder permiso al código firmado por susan para leer cualquier fichero en el directorio C:\TestData, necesitamos crear una entrada de política concediendo este permiso. Observa que "Code signed by susan" es una abreviatura de decir "Código en un fichero class contenido en un fichero JAR, donde JAR fue firmado usando la clave privada correspondiente a la clave pública que aparece en un certificado del keystore en una entrada con el alias susan."

Elegimos el botón Add Policy Entry en la ventana principal de Policy Tool. Esto nos trae la caja de diálogo Policy Entry.

Usando esta caja de diálogo, tecleamos el siguiente alias en la caja de texto SignedBy.

susan

Dejamos la caja de texto CodeBase en blanco, para cenceder permiso a todo el código firmado por susan, el permiso, sin importar de donde venga.

Nota: si queremos restringir el permiso sólo para el código firmado por susan que venga del directorio C:\Test\, deberíamos teclear la siguiente URL en la caja de texto CodeBase.

file:/C:/Test/*

Para añadir el permiso, elgimos el botón Add Permission. Esto nos trae la caja de diálogo Permissions.

Hcemos lo siguiente.

  1. Elegimos File Permission desde la lista desplegable Permission. El nombre del permiso completo (java.io.FilePermission) aparece en la caja de texto que hay a la derecha de la lista desplegable.
  2. Tecleamos esto en la caja de texto que hay a la derecha de la lista etiquetada Target Name para especificar todos los ficheros del directorio C:\TestData\.
    C:\TestData\*
    
  3. Escpecificamos el acceso de lectura eligiendo la opción read en la lista desplegable Actions.

Ahora la caja de Diálogo Permissions se parecerá a esto.

Elegimos el botón OK. El nuevo permiso aparece en una línea en el diálogo Policy Entry, de esta forma.

Nota: Cada barra invertida que hayamos tecleado en el path del fichero ha sido reemplazada por dos barras invertidas, por conveniencia. Las cadenas en un fichero de política son procesadas por un tokenizer que permite usar "\" como caracter de escape (por ejemplo \n para indicar nueva línea), por eso el fichero de política requiere dos barras invertidas para indicar una sóla barra invertida. Si usamos una sola barra invertida como separadores de directorios, Policy Tool las convierte automáticamente en dobles barras invertidas.

Ahora ya hemos especificado la entrada de política, elegimos el botón Done en el diálogo Policy Entry. La ventana Policy Tool contiene una línea que representa la entrada de política, mostrando el valor SignedBy, como se ve en la figura.

. Grabar el Fichero de Política

Para grabar el nuevo fichero de polícia que hemos creado, elegimos el comando Save As en el menú File. Esto nos trae la caja de diálogo Save As.

Navegamos por la estructura de directorio para obtener el directorio en el que salvar el fichero de política: el directorio Test del disco C:. Tecleamos el nombre de fichero.

raypolicy

Luego elegimos el botón Save. Entonces se graba el fichero de política, y su nombre y path se muestran en la caja de texto etiquetada Policy File, como se muestra en la siguiente figura.

Luego salimos de Policy Tool seleccionando el comando Exit del menú File.

. Ver los efectos del Fichero de Política

En los pasos anteriores hemos creado una entrada en el fichero de política raypolicy concediendo permiso al código firmado por susan para leer ficheros en el directorio C:\TestData\ (o el directorio testdata en tu directorio home si estámos trabajando en UNIX). Ahora deberíamos poder ejecutar con éxito el programa Count para leer y contar los caracteres de un fichero del directorio especificado, incluso aunque estemos ejecutando la aplicación con un controlador de seguridad.

Como se describe al final de la lección Visión Rápida para Controlar Applet, hay dos formas posibles en la podemos considerar el fichero de política raypolicy como parte de la política general, además de los ficheros de política especificados en el fichero de propiedades de seguridad. La primera aproximación es especificar el fichero de política adicional en una propiedad pasada el sistema de ejecución. La segunda aproximación es añadir una línea al fichero de propiedades de segurdad específicando el fichero de política adicional.

. Aproximación 1

Podemos usar un argumento de la línea de comandos -Djava.security.policy para especificar un fichero de política que debería usarse en adicción o en lugar de alguno de los especificados en el fichero de propiedades de seguridad.

Para ejecutar la aplicación Count y tener incluido el fichero de política raypolicy, tecleamos esto, en una sóla línea, en el directorio que contiene los ficheros sCount.jar y raypolicy.

java -Djava.security.manager -Djava.security.policy=raypolicy
  -cp sCount.jar Count C:\TestData\data

El programa debería devolver el número de caracteres en el fichero especificado.

Si todavía informa un error, algo hay erróneo en el fichero de política. Usamos Policy Tool para comprobar el permiso que acabamos de crear en el "paso anterior".

. Aproximación 2

Podemos especificar un número de URLs -- incluidas algunas con la forma "http://" -- en propiedades policy.url.n en el fichero de propiedades de seguridad, y se cargarán todos los ficheros de política especificados.

Por eso una forma de hacer que nuestra entrada en el fichero de política raypolicy sea considerada por el intérprete es añadir una entrada indicando este fichero en el fichero de propiedades de seguridad.

Importante: Si estas ejecutando tu propia copia del JDK, puedes fácilmente editar tu fichero de propiedades de seguridad. Si estás ejecutando una versión compartida con otros, sólo podrás modificarlo si tienes acceso de escritura, o si pides al admistrados que modifique el fichero de la forma apropiada. Sin embargo, no es apropiado realizar modificaciones en un fichero de seguridad para todo el sistema sólo para probar este tutorial. Te sugerimos que leas los pasos siguientes para ver cómo se hace o que te instales tu propia versión privada del JDK para usar con las lecciones del tutor.

El fichero de propiedades de seguridad está alojado en

  Windows.
    java.home\lib\security\java.security 
  UNIX.
    java.home/lib/security/java.security

La porción java.home indica el directorio en el que se instaló el JRE.

Para modificar el fichero de propiedades de seguridad, lo abrimos en un editor que permita editar ficheros de texto ASCII. Luego añadimos la siguiente línea después de la línea que empieza con policy.url.2.

  Windows.
    policy.url.3=file:/C:/Test/raypolicy
  UNIX.
    policy.url.3=file:${user.home}/test/raypolicy

En un sistema UNIX podemos específicar explícitamente nuestro directorio home, como

policy.url.3=file:/home/susanj/test/raypolicy

Luego, en nuestra ventana de comandos, vamos al directorio que contiene el fichero sCount.jar, que es, el directorio C:\Test o ~/test. Y tecleamos el siguiente comando.

java -Djava.security.manager
        -cp sCount.jar Count C:\TestData\data

Como en la aproximación 1, si el programa aún muestra algún error, tenemos algo erróneo en el fichero de política. Usamos Policy Tool para comprobar el permiso que acabamos de crear en el "paso anterior".

Importante: Antes de continuar probablemente querrás borrar la línea que acabamos de añadir al fichero de propiedades de seguridad, ya que no querrás que el fichero raypolicy sea incluido cuando no estás ejecutando las lecciones del tutor.

 
Patrocinados
 

Copyright © 1999-2006 Programación en castellano. Todos los derechos reservados.
Formulario de Contacto - Datos legales - Publicidad

Hospedaje web y servidores dedicados linux por Ferca Network