miércoles, 26 de diciembre de 2012

Instalar un servicio de Windows en una máquina de 64 bits

Si el PC con el que desarrollas es una máquina de 32 bits y el servidor en el que se va a instalar es de 64 bits puedes tener algunos problemas para realizar la instalación, ya que el instalador generado no funcionará.

Lo primero a tener en cuenta es que debes compilar todos los proyectos que incluyan el servicio, el propio servicio y todos los proyectos satélites, en x64. Esto se hace en la sección "Generar" de la ventana de propiedades de cada proyecto. Yo no lo dejaría en AnyCPU ya que no siempre funciona correctamente.

Pero con esto no es suficiente, ya que el instalador de Visual Studio, al menos hasta la versión 2008, tiene un  pequeño bug. Aunque la plataforma de destino sea x64, para generar el instalador Visual Studio usa una librería del sistema (InstallUtilLib.dll) compilada en 32 bits. Por tanto, al instalar el servicio en un servidor x64 se genera una excepción del tipo “BadImageFormat”.


Para solucionar este problema debes reemplazar la librería (InstallUtilLib.dll) introducida en 32bits  en el .msi instalador por la librería de 64bits.

Para reemplazar la librería debes seguir los siguientes pasos:

  1. Abre el fichero .msi generado en Orca
    1. Si no tienes instalada la aplicación Orca de Microsoft es necesario que la descargues e instales.
  2. Selecciona “Binary table”
  3. Haz doble click en la celda [Binary Data] para el registro “InstallUtil”
  4. Asegúrate de que “Read binary from filename” está seleccionado  y pulsa sobre el botón “Browse”
  5. Navega hasta la ruta %WINDIR%\Microsoft.NET\Framework64\v2.0.50727
    1. Esta ruta solo está disponible en máquinas con arquitectura de 64Bits, por tanto debes seleccionar esta ruta en un servidor remoto, o copiar este fichero desde un servidor a tu máquina local.
  6. Selecciona “InstallUtilLib.dll”
  7. Pulsa en el botón “Open”
  8. Pulsa en el botón “OK”
  9. Guarda el .msi


Este .msi ya es posible instalarlo en un servidor de 64Bits.



miércoles, 12 de diciembre de 2012

Usar un fichero Excel desde un servicio de Windows


Si intentas manejar un fichero Excel con las librerías de interoperalilidad desde un servicio de Windows desarrollado en .Net, te encontrarás con una Excepción poco esclarecedora: "Microsoft Office Excel cannot access the file".

El problema se debe a que un servicio de Windows, independientemente del usuario de ejecución que se configure, se ejecuta en un perfil especial, el systemprofile. Este perfil no tiene una carpeta de escritorio, sin embargo la librería de interoperabilidad de Excel, para modificar un documento Excel, lo intenta abrir en segundo plano en el escritorio. Al no existir la ruta, se provoca esta excepción.

Por tanto, en el momento de la instalación es necesario crear la carpeta de escritorio (Desktop) en función de la arquitectura del servidor:


  • Servidor de 32bits: %WINDIR%\System32\config\systemprofile\Desktop
  • Servidor de 64bits: %WINDIR%\SysWOW64\config\systemprofile\Desktop


martes, 11 de diciembre de 2012

Cifrar el fichero de configuración con RSA

Un problema recurrente es tener que proteger tu fichero de configuración, app.config o web.config, de miradas indiscretas.

Para realizar el cifrado de estos ficheros podemos usar el contenedor de claves RSA. En función de dónde se desplegará la aplicación y qué usuarios deben tener acceso al fichero de configuración descifrado, se puede usar el contenedor de claves RSA de dos maneras, o bien usar el contenedor por defecto, o bien usar un contenedor personalizado.

  • Contenedor por defecto: No tienes que preocuparte de crear el contenedor, ni adaptar la configuración de tu fichero a un contenedor específico. Por contra escogiendo este método no es posible migrar el fichero de configuración cifrado de un equipo a otro o tener una aplicación distribuida en diferentes máquinas con un único fichero de configuración.
  • Contenedor personalizado: Permite la distribución de una aplicación utilizando el mismo cifrado en diferentes máquinas. Además permite el control del acceso a la información descifrada por usuario o grupo de usuarios.
Sin ninguna duda es mejor opción utilizar un contenedor personalizado, ya que el aumento de esfuerzo es casi nulo y ofrece mucha más versatilidad. Por tanto, en esta entrada se va a explicar cómo cifrar tu fichero de configuración utilizando un contenedor de claves RSA personalizado.

En este ejemplo se va a mostrar como cifrar un fichero app.config, sin embargo el proceso para cifrar un fichero web.config es completamente análogo.

Para cifrar el fichero de configuración se deben seguir los siguientes pasos:

  1. Crear el contenedor de claves
  2. Crear el proveedor de cifrado personalizado
  3. Cifrar el fichero usando "EntLib Config"

Crear contenedor de claves

El primer paso es crear el contenedor de claves a utilizar. Por si en un futuro se quiere migrar la aplicación a otro servidor o implantarlo en diversas máquinas, es importante crear este contenedor como 'exportable'. Todas las instrucciones para manejar los contenedores de claves RSA las puedes encontrar en esta entrada: Manejar el contenedor de Claves RSA.


Crear proveedor de cifrado personalizado

El siguiente paso es indicar en el fichero de configuración cuál es el contenedor de claves que debe utilizar. Para ello se creará un nuevo proveedor de cifrado RSA introduciendo dentro de la sección <configuration> la siguiente clave:

<configprotecteddata> 
 <providers> 
  <remove name="RSAProtectedConfigurationProvider"> 
    <add 
      description="Uses RsaCryptoServiceProvider to encrypt and decrypt" 
      keycontainername="nombreClave" 
      name="RsaProtectedConfigurationProvider"  
      type="System.Configuration.RsaProtectedConfigurationProvider, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" 
      usemachinecontainer="true"> 
    </add>
  </remove>
 </providers>
</configprotecteddata>

En esta clave se ha de cambiar el valor de keycontainername por el nombre que se le haya dado al contenedor en el momento de su creación. Adicionalmente se puede proporcionar una descripción diferente al proveedor de RSA.


Cifrar el fichero usando "EntLib Config"

Al instalar las Enterprise library 4 o superior (no sé si con versiones anteriores también), se instala la herramienta de configuración de Enterprise Library, esta herramienta se llama "Ent Lib Config". Se intalarán distintas versiones de esta herramienta teniendo que elegir la versión adecuada en cada momento, en función de la versión del framework del proyecto (3.5 o 4) y de la arquitectura de la máquina (32 o 64 bits).

Se debe abrir el fichero de configuración con esta herramienta Ent Lib Config, para ello se puede abrir la aplicación y buscar el fichero o dentro del Visual Studio: pulsar botón derecho sobre el fichero de configuración > Edit Enterprise Library V5 Configuration.

Editar fichero de configuración con Ent Lib Configuration desde Visual Studio

El fichero de configuración se cifra por secciones, no se cifra entero. es decir, se puede cifrar la sección de cadenas de conexión pero no cifrar la sección de AppSettings. Para cifrar una sección hay que seguir los siguientes pasos:

Desplegar las opciones de la sección a cifrar pulsando en el botón: 

Seleccionar en la opción "Cifrado" el valor "RsaProtectedconfigurationProvider"



Resultado final

Fichero sin cifrar:



Fichero con sección AppSettings cifrada:




lunes, 12 de noviembre de 2012

Manejar el contenedor de Claves RSA

En mi entrada anterior he explicado brevemente qué es el Contenedor de claves RSA, en esta entrada veremos como trabajar con él.

Las operaciones que voy a explicar en esta entrada son:
  • Creación
  • Exportación
  • Importación
  • Conceder permisos
  • Denegar permisos
  • Eliminación del contenedor
Todas estas operaciones se realizarán desde el CMD del equipo en cuestión. Todas estas operaciones se realizan con el comando aspnet_regiis, este comando se encuentra en la carpeta Microsoft.NET dentro de la carpeta de Windows. Dentro de la carpeta Microsoft.NET hay que buscar la carpeta exacta, ya que cambia en función de si el equipo tiene una arquitectura de 32 o 64 bits. La ruta exacta suele ser C:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727

Creación de un nuevo contenedor

Dentro de una única máquina se pueden tener diversos contenedores, cada vez que se cree uno se generará una clave nueva y a este nuevo contenedor se le pueden asignar permisos a diferentes usuarios o grupos.

La sintaxis para crear un nuevo contenedor es la siguiente:

aspnet_regiis -pc "appKeys" -exp

Dónde:
  • aspnet_regiis es el comando del CMD.
  • -pc es el parámetro que indica que se crea un nuevo contenedor.
  • "appKeys" es el nombre que se le ha dado al contenedor.
  • -exp es el parámetro que indica que el contenedor es exportable.

El parámetro -exp es especialmente importante para permitir utilizar este contenedor en despliegues en otras máquinas.

Exportación de un contenedor

Una vez creado un contenedor se puede exportar a un fichero xml. Este fichero se utilizará posteriormente para utilizar este mismo contenedor en una segunda máquina.

La sintaxis para exportar un contenedor es la siguiente:

aspnet_regiis -px "appKeys" "D:\ExportContainers\appKeys.xml" -pri


Dónde:
  • aspnet_regiis es el comando del CMD.
  • -px es el parámetro que indica que se exporta el contenedor.
  • "appKeys" es el nombre que se le ha dado al contenedor.
  • "D:\ExportContainers\appkeys.xml" es la ruta en la que se guardará el fichero de exportación.
  • -pri es el parámetro que indica que se deben incluir las claves privadas en el fichero de exportación. Sin esta información no se podrían hacer correctamente las importaciones en otras máquinas.

Importación de un contenedor

Una vez generado el xml de exportación del contenedor ya puedes importarlo en otras máquinas.
Para ello el primer paso es copiar el xml generado al disco de la máquina donde quieras importar el contenedor.

Una vez copiado has de utilizar el siguiente comando:

aspnet_regiis -pi "appKeys" "D:\ImportContainers\appKeys.xml"

Dónde:
  • aspnet_regiis es el comando del CMD.
  • -pi es el parámetro que indica que se importa un contenedor.
  • "appKeys" es el nombre que se le ha dado al contenedor.
  • "D:\ImportContainers\appkeys.xml" es la ruta en la que se encuentra el fichero a importar.

Conceder permisos sobre un contenedor

Una vez importado el contenedor, el siguiente paso es concederle los permisos adecuados. Estos permisos se deberán conceder al usuario de ejecución de la aplicación (por ejemplo el usuario configurado en IIS como usuario de aplicación) y a los usuarios que deban tener acceso al usuario, pro ejemplo los administradores de la aplicación que deben poder cambiar los valores de un fichero de configuración.

Estos permisos pueden concederse a un usuario concreto o a un grupo del Active Directory, para ambos casos la sintaxis es la misma.

aspnet_regiis -pa "appKeys" "domain\userName"

Dónde:
  • aspnet_regiis es el comando del CMD.
  • -pa indica que se le están concediendo permisos a un usuario o grupo.
  • "appKeys" es el nombre del contenedor sobre el que se están asignando permisos.
  • "domain\username" es el nombre del usuario o grupo (con el prefijo del dominio) al que se está concediendo acceso al contenedor.

Denegar permisos a un contenedor

De la misma forma que necesitamos conceder permisos a un usuario sobre un fichero, en un momento dado podemos necesitar denegarle esos permisos.

Para denegarle los permisos se usará esta sintaxis:

aspnet_regiis -pr "appKeys" "domain\userName"

Dónde:
  • aspnet_regiis es el comando del CMD.
  • -pr indica que se le están denegando permisos a un usuario o grupo.
  • "appKeys" es el nombre del contenedor sobre el que se están denegando permisos.
  • "domain\username" es el nombre del usuario o grupo (con el prefijo del dominio) al que se está denegando acceso al contenedor.

Eliminar un contenedor

En caso de querer eliminar un contenedor creado se debe utilizar la siguiente sintaxis:

aspnet_regiis -pz "appKeys"

Dónde:
  • aspnet_regiis es el comando del CMD.
  • -pz indica que se borra el contenedor indicado.
  • "appKeys" es el nombre del contenedor a borrar.

martes, 6 de noviembre de 2012

Contenedor de Claves RSA

Empecemos con qué es eso de RSA. RSA es un sistema criptográfico de clave única, apto tanto para cifrado de cadenas como para firmas digitales.

Este sistema de criptografía permite tanto el cifrado como el descifrado, por tanto es válido, por ejemplo, para el cifrado de fichero de configuración.

Como apunte, saber que existen otros cifrados de una sola dirección (one way) que no permiten descifrado. Es habitual utilizar estos algoritmos para cifrar contraseñas, ya que con comparar la contraseña  guardada ya cifrada con la cadena cifrada resultante de la introducción de la contraseña por parte del usuario es suficiente.

El sistema de cifrado RSA requiere de una clave privada a partir de la cual se generarán las cadenas cifradas y esta misma clave se usará para descifrar la cadena encriptada y recuperar el texto original. Sin conocer la clave privada no es posible descifrar los datos, por tanto, la seguridad de este algoritmo depende de la privacidad de la clave privada.

Windows crea asociado a cada usuario del Sistema Operativo un contenedor de claves para RSA. Este contenedor de claves simplemente es un repositorio protegido por usuario con un texto generado de manera automática por el sistema operativo al crear un nuevo almacén y que podrás utilizar desde tus aplicaciones como clave privada para los cifrados.

El problema inicial que tienen estos contenedores de claves es que están asociados al usuario y a la máquina en la que se generan, sin embargo, existe la posibilidad de exportarlos/importarlos y asignarles permisos a un usuario concreto. Utilizando estas funcionalidades puedes asignar un único contenedor al cifrado de archivos de aplicaciones distribuidas en diferentes máquinas y a los que tienen acceso diversos usuarios.

Además, tienen la ventaja de que puedes crear tantos contenedores como quieras, pudiendo dar permisos sobre un contenedor a un equipo y a otro equipo acceso a otro contenedor. De esta forma consigues determinar qué usuario o grupo de usuarios tienen acceso a unos ficheros concretos.

lunes, 17 de septiembre de 2012

Mover hojas de Excel dentro de un libro con vb.Net

Este artículo explicará cómo ordenar a tu antojo las hojas de un libro Excel utilizando el API de interoparibilidad.

Para este ejemplo vamos a suponer que hemos creado ya un Excel y rellenado el contenido de dos hojas llamadas "Datos" e "INFORME". La Hoja Excel la hemos generado en una variable llamada ficheroExcel.

Al generar la hoja Excel con nuestro código, la hoja "INFORME" se muestra en primer lugar y queremos colocarla detrás de la hoja "DATOS".

Para ordenar las hojas solo tenemos que escribir la siguiente línea de código:


ficheroExcel.Sheets("INFORME").Move(After:=ficheroExcel.Sheets("DATOS"))