Assemblies (Ensamblados) II

De los Ensamblados Compartidos, su Nombre Unico y la GAC

Por Willy Marroquín

Bb972218.downlanim(es-es,MSDN.10).gifDescargar ejemplos de este artículo (16 KB).

Contenido

 Introducción
 Objetivos
 El ensamblado compartido
 Uso de Clave Pública
 Creación de las Llaves
 Entonces solo falta copiar el ensamblado en la GAC... ¿O no?
 Utilizando el GACUtil.exe
 Utilizando Microsoft .NET Framework Configuration
 Ya registré mi ensamblado en la GAC, ¿Porqué no aparece en la ventana de referencias del IDE?

Introducción

En el artículo anterior,  Assemblies (Ensamblados) - De la Composición y Ensamblados Privados **, se realizó un acercamiento a la composición y análisis de un ensamblado; se verificó su composición con ILDASM; se probó el funcionamiento probing, el aislamiento del registro, analizamos el AssemblyInfo junto con la definición y aplicación de los ensamblados privados. En este segundo acercamiento trataremos sobre los ensamblados compartidos; su trabajo con cifrado y el trabajo junto con el caché de ensamblados global GAC (Global Assemblie Cache).

 

Objetivos

  • Comprender la funcionalidad y aplicabilidad de los Ensamblados Compartidos.

  • Entender la mecánica de funcionamiento mediante Nombres Seguros (Strong Name).

  • Analizar y entender a fondo el papel de GAC.

  • Entender la utilización de las herramientas existentes para Ensamblados Privados.

 

El ensamblado compartido

Tomando como principio que los ensamblados poseen arquitectónicamente la misma estructura, independientemente de su nivel de visibilidad (privado o compartido) y que por ende la definición de ensamblado conlleva a la unicidad en su concepto, entraremos a detallar la diferencia conceptual y de comportamiento en los ensamblados compartidos.

Con naturalidad un ensamblado privado puede convertirse en compartido, llevando a cabo una serie de tareas que veremos a lo largo de este artículo. Un ensamblado privado no es compartido de manera directa, por que el primero no cuenta con un identificador universal o lo que es igual, no aporta la información requerida para identificarse de manera única.

Dentro de las  justificaciones principales para crear un ensamblado compartido, están:

  • Buscar un rendimiento más alto. Si un ensamblado compartido es llevado a memoria por una aplicación y otra aplicación hace un llamado al mismo, la integridad y consistencia del ensamblado no llevará otro proceso de verificación y se basará en el primer llamado. Esto trae de la mano un menor consumo de memoria, pues una misma instancia puede dar respuesta a todas las aplicaciones que le hagan solicitud.

  • Procesos de actualización. Debido a que los ensamblados compartidos tienen un único sitio de residencia, los procesos de actualización son, por mucho, más simples.

 

Uso de Clave Pública

.NET usa una tecnología para generar un identificador universal, que permite  tan solo a quien suministre determinada información sobre un ensamblado compartido (previamente compilado) generar nuevas versiones del mismo, basándose en criptografía de clave pública. Esta se diferencia de las mecánicas clásicas de cifrado en la utilización de una llave tanto para cifrar la información (clave privada) y otra para el proceso inverso (clave pública) es decir, con la clave privada se cifran los datos que serán descifrados exclusivamente por la clave pública. Las llaves empleadas para estas tareas se almacenan físicamente, lo que permitiría limitar la creación de nuevas versiones tan solo restringiendo el acceso a ellas. Sin embargo, este mecanismo sólo asegura que las posteriores versiones del ensamblado sean realizadas por la misma persona (entidad o compañía) que realizó la o las versiones previas del ensamblado, más no su funcionalidad es decir, esto no asegura que el contenido del ensamblado no pudiere ser "malicioso"; para ello se debe realizar un proceso de firmas, que asegurará el contenido ejecutorio del ensamblado.

Esta algoritmia de clave pública es utilizada dentro de .NET con una característica llamada generación de nombre único (Strong Name), que brinda la posibilidad de generar el identificador universal. Para tal tarea, se usan datos tales como la cultura, la versión, el tamaño, el nombre único y una clave pública basada en hash; esta última utilizará las referencias a otros ensamblados requeridos dentro de la compilación,  más el contenido propio del ensamblado.

Gracias a esta cantidad de datos utilizados, las posibilidades de un ensamblado gemelo son casi de 0. Al ejecutarse de nuevo el ensamblado, el CLR leerá toda esta información y procederá a buscar un ensamblado con una definición y nombre iguales, mediante tareas de validación para verificar la integridad del ensamblado, previniendo así la adulteración o modificación intencional. La idea es recalcular el valor hash y comprobarle por su llave pública para poderle descifrar. Si no se encuentran diferencias, se cargará en memoria el ensamblado, de otra forma se lanzará una excepción. La mayoría de los procesos mencionados anteriormente se suceden de forma transparente, limpia, y sin intervención de quien desarrolla.

¿Cómo creo el nombre seguro ( Strong Name )?

Se deben obtener las dos (2) llaves (privada y pública). Esto se realiza una sola vez por norma general, para luego darle el nombre al ensamblado por medio de las llaves ya creadas.

 

Creación de las Llaves

Utilizaremos SN.exe (StrongName), el cual generará las llaves; para ello utilizaremos el ensamblado que acompaña este artículo (Aforismo.dll); ver Figura 1.

Bb972218.art219-img01-570x318(es-es,MSDN.10).jpg
Figura 1: Utilización de SN para generación de las llaves. Volver al texto.

Después de crear las llaves (en un archivo, por defecto, de 596 bytes), éstas deberían almacenarse en un lugar seguro (para evitar problemas de adulteración sobre las mismas). Luego abriremos el proyecto desde el IDE de VS .NET, y haremos la asociación del ensamblado con las llaves (MisLlaves.key, para este ejemplo). Para ello utilizaremos el AssemblyInfo.vb (Ver Figura 2 y Figura 3).

Bb972218.art219-img02-326x318(es-es,MSDN.10).jpg
Figura 2: Código almacenado en el AssemblyInfo.vb. Volver al texto.

Bb972218.art219-img03-228x301(es-es,MSDN.10).jpg
Figura 3: Vista del Solution Explorer.Volver al texto .

Tras realizar la compilación y analizar el ensamblado mediante ILDASM.exe, en el manifiesto del mismo encontraremos una sección llamada Publickey (Ver Figura 4), que antes de hacer la asociación y compilación no existía. Bastó realizar dos (2) sencillas operaciones, asegurar el nombre único con SN y realizar la asociación del Asseblyinfo, para que en adelante una instacia pasara a atender todas las aplicaciones que le soliciten, asociando a un único archivo físico que responda a esta tarea.

Bb972218.art219-img04-510x291(es-es,MSDN.10).jpg
Figura 4: Vista del Manifiest de Aforismo.dll, mediante IDLASM.exe. .Volver al texto

Después de realizar esta tarea, resulta conveniente ubicar nuestro ensamblado en la caché de ensamblados global (GAC), ya que dentro de sus funcionalidades está la de ubicar a los ensamblados compartidos en un solo lugar. 

 

Entonces solo falta copiar el ensamblado en la GAC... ¿O no?

Analizando la GAC en detalle

Para empezar diremos que la GAC está ubicada por defecto en C:\Windows\Assembly (Ver Figura 5); la idea básica de colocar nuestro ensamblado en la GAC es ampliar la visibilidad a todas las aplicaciones .NET de la máquina. Sería el equivalente al proceso de registro con el modelo COM. Cuando se agrega un ensamblado a la GAC, se verifican todos y cada uno de los archivos que forman parte de éste, para asegurar su funcionalidad. Otra de las tareas de la GAC es mantener más de una versión de un mismo ensamblado, permitiendo que una nueva instalación de un ensamblado no afecte a las anteriores.

Bb972218.art219-img05-570x125(es-es,MSDN.10).jpg
Figura 5: Vista de la GAC desde el Explorador de Windows. Volver al texto.

La estructura de subdirectorios interna es algo más extensa que la exhibida en el Explorador de Windows (utilizaremos el ensamblado CRVsPackageLib como referencia para el desarrollo del siguiente ejercicio). Si se observa dicha estructura desde la línea de comandos, se podrá verificar que ésta es un poco distinta de lo mostrado en el Explorador de Windows (Ver Figura 6).

Bb972218.art219-img06-570x502(es-es,MSDN.10).jpg
Figura 6: Vista de la línea de comandos dentro de la GAC. Volver al texto.

En los puntos 1 y 2 de esta figura, tras ejecutar un DIR, vemos que existe un subdirectorio dedicado a la GAC y otros dos (2) dedicados a referencias del Framework (aquí denotados como NativeImages1_v1.0.3705 y NativeImages1_v1.1.4322 . Es factible que en tu máquina solo exista uno, dependiendo de si has trabajado con más de una versión del Framework. Los números v1.0.3705  y 1_v1.1.4322 corresponden a los números de versión de los mismos). En los puntos 3 y 4, observamos el contenido del subdirectorio NativeImages1_v1.0.3705 (correspondiente a la versión más reciente instalada en esa máquina) que exhibe los referentes BCL (Base Class Library). Finalmente en el punto 5 está el listado de ensamblados registrados en la GAC y aparece desde luego CRVsPackageLib, que era nuestro referenciado en la Figura 5.

Si observamos dentro del ensablado referencia CRVsPackageLib (Ver Figura 7), en el punto 1 veremos su versión colocada dentro de un folder (para este caso 1.0.0.0__692fbea5521e1304, dado por concatenar su versión más el PublicToken). Si hubiera más de una versión del mismo ensamblado, se mostraría un subdirectorio con el folder correspondiente.

En el punto 2 se observa el ensamblado propiamente dicho CRVsPackageLib.dll y un archivo de configuración, __AssemblyInfo__.ini (estándar en su conformación para todos los ensamblados que reposan en la GAC). Por último, en el punto 3 podemos observar los datos que se despliegan dentro del Explorador de Windows (Nombre, Versión , Cultura, PublicToken) que concuerdan con los mostrados en la Figura 5..

Bb972218.art219-img07-570x440(es-es,MSDN.10).jpg
Figura 7: Al interior del directorio referente al ensamblado CRVsPackageLib. Volver al texto.

 

Utilizando el GACUtil.exe

Tras analizar la GAC, entraremos en el proceso de registro del ensamblado que acompaña este artículo (Aforismo.dll ) en la GAC. Si bien podría pensarse que bastaría con copiar el ensamblado en el subdirectorio GAC, se debe tener en cuenta que la GAC lleva a cabo ciertas tareas de validación que el mecanismo de Copy o arrastre no permiten realizar. Todo esto en pro de mantener la integridad sobre el ensamblado. Se debe tener en cuenta que solo los usuarios que posean permisos de administrador podrán instalar o eliminar archivos de la GAC. Existen varias formas de agregar un ensamblado a la GAC, una de ellas es mediante la aplicación de la herramienta de línea de comandos GacUtil.exe (las otras dos (2) vías son utilizar la aplicación de configuración de Windows o un paquete de instalación). En la Figura 8 veremos la utilización de GACUtil.

Bb972218.art219-img08-570x431(es-es,MSDN.10).jpg
Figura 8: Utilización de GACUtil.exe. Volver al texto.

En el punto 1 de la Figura 7 ejecutamos GACUtil con el modificador /i y el nombre del ensamblado (gacutil /i Aforismo.dll, en este caso). Si el paso de generar el nombre fuerte (Strong Name SN.exe ) ha sido realizado, retorna un mensaje de éxito de la cuestión, verificable inmediatamente dentro de la GAC (Figura 9). Si se quiere realizar el proceso inverso es decir, eliminar la referencia del ensamblado, se utiliza el modificador /u (gacutil /u Aforismo.dll, para este caso), puntos 2 y 3. Se debe tener en cuenta que  al utilizar solo /u, se eliminarán todas las entradas correspondientes a este ensamblado. Si se desea eliminar una de ellas en particular, se debe especificar por lo menos la versión; por ejemplo:

gacutil /u Aforismo.dll,Version=1.0.1222.27044,PublicToken=7c8ea15bea113fb5 

Bb972218.art219-img09-469x107(es-es,MSDN.10).jpg
Figura 9: Vista del explorador de Windows sobre la GAC, después de utilizar gacutil /i Aforismo.dll. Volver al texto.

 

Utilizando Microsoft .NET Framework Configuration

Otra manera de agregar un ensamblado a la GAC consiste en utilizar una consola llamada Microsoft .NET Framework Configuration, ubicada dentro de las Herramientas Administrativas (si tu máquina posee la versión 1.1 del framework, ésta aparece como Microsoft .NET Framework 1.1 Configuration, ver Figura 10).

Bb972218.art219-img10-570x275(es-es,MSDN.10).jpg
Figura 10: Consola gráfica para registro de ensamblados globales. Volver al texto.

Tras seguir el asistente de ubicación física, el ensamblado quedará registrado en la GAC (). El proceso de eliminación es tan sencillo como eliminar con el botón secundario o pulsar la tecla Del. (Ver Figura 11).

Bb972218.art219-img11-570x299(es-es,MSDN.10).jpg
Figura 11: Consola gráfica para el registro de ensamblados, en estado de eliminación. Volver al texto.

 

Ya registré mi ensamblado en la GAC, ¿Porqué no aparece en la ventana de referencias del IDE?

Cuando se agrega un nuevo ensamblado a la GAC, la lista de ensamblados mostrados en "agregar referencias del IDE" no aparece en las referencias, pues no existe una relación directa con los ensamblados que se marquen como compartidos ... Esto puede parecer un poco desconcertante; se puede tomar como punto a favor de esta mecánica el hecho de poder seleccionar cuáles ensamblados serán mostrados y cuáles no ... Aunque para algunas personas sería deseable una lista total de los ensamblados. Para lograr tal cosa se puede agregar una llave dentro de HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\AssemblyFolders\ y agregar un valor que deberá apuntar al subdirectorio que posea los ensamblados que se desea aparezcan en las referencias (Ver Figura 12 y Figura 13).

Bb972218.art219-img12-432x131(es-es,MSDN.10).jpg
Figura 12: Consola gráfica del registro de Windows (regedit.exe), HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\AssemblyFolders\Aforismo. Volver al texto.

Bb972218.art219-img13-566x446(es-es,MSDN.10).jpg
Figura 13: Al abrir un proyecto y adicionar una referencia aparcerá el ensamblado, según el  nombre del ensamblado en el atributo AssemblyTitle dentro de AssemblyInfo; en nuestro ejemplo "Aforismos de Nietzche" (Ver Figura 2).Volver al texto.

En un próximo artículo abordaremos el tema de las políticas de publicación sobre los ensamblados, causa y efecto.

Bb972218.willy_marroquin(es-es,MSDN.10).gif Willy Alexánder Marroquín ha trabajado 8 años en la construcción de software de manera profesional y está especializado en el desarrollo sobre la plataforma .net. Ha participado en varios proyectos que han sido galardonados a nivel internacional por Microsoft. Cuenta con las certificaciones MCP, MCSD, MCT y MCAD. Su otro frente son las Ciencias Humanas; está especializado en filosofía Nietzscheana y es estudiante de Psicología Social en la Universidad Nacional de Colombia.