Firma de código en macOS: Lo que los Desarrolladores han de saber, Parte 1

Tu app de macOS está finalizada y lista para distribuir; pero salvo que tengas pensado ejecutarla sólo en tu propio equipo, existe un paso esencial que has de realizar antes de que puedas compartirla con otros usuarios: la firma del código mediante el uso de certificados.

Esta serie de artículo tiene como objetivo proporcionar una visión clara y práctica sobre cómo funcionan los certificados, con un especial enfoque en la firma y distribución de aplicaciones macOS. Algunos conceptos se aplican a los certificados digitales en general, mientras que otros son específicos al proceso de firmado del código en aplicaciones macOS. Al final de la serie comprenderás mejor qué son los certificados, por qué importan, y el papel que juegan en la creación y distribución de una app macOS.

Nuestro punto de partida es el campo Developer ID en el panel Inspector correspondiente a Build Settings > macOS > Sign:

Por omisión, este campo está vacío. Cuando haces clic en el botón Build, el bundle de la app (y sus contenidos) se firmarán utilizando la configuración de seguridad más relajada. Dicha opción no precisa del uso de un certificado de desarrollador en particular y, por tanto, no verifica que la app provenga de un desarrollador conocido y confiable.

Este tipo de firma se denomina Ad-Hoc. Es perfectamente válida cuando depuras la app desde el IDE de Xojo o cuando compilas apps que pienses ejecutar sólo localmente, en tu equipo.

En anteriores versiones de macOS era posible distribuir y ejecutar sobre otros Mac las aplicaciones firmadas como Ad-Hoc; siempre y cuando el usuario confiase en su ejecución, y procedencia, de forma explícita. Si bien esto aun puede hacerse desde un punto de vista técnico, lo cierto es que las versiones de macOS más recientes están restringiendo cada vez más todo lo relacionado con la seguridad en la ejecución de aplicaciones y, como resultado, hace que resulte más complejo para los usuarios la ejecución de apps firmadas como Ad-Hoc.

En la mayoría de los casos Gatekeeper entrará en juego para evitar la ejecución de la app. Dado que el sistema no podrá verificar la identidad de un desarrollador confiable, tratará la app como no verificada. Con una firma de tipo Ad-Hoc, macOS sólo confirmará que la app no ha sido modificada desde su firma, pero no podrá validar quién la ha firmado.

Bajo el capó: así funciona la firma “Ad-Hoc”

Cada vez que se firma una app (incluyendo todos los contenidos de su bundle), macOS utiliza la herramienta de Apple codesign. Cuando se aplica una firma Ad-Hoc, el proceso de firma funciona, de forma simplificada, tal y como se puede ver en el siguiente esquema:

  • Se calcula un valor hash (una huella digital única) para cada uno de los archivos encontrados en el bundle de la app, tanto si se trata de un ejecutable como si no, así como sobre el propio bundle propiamente dicho.
  • Estos valores hash se almacenan en el bundle de la app, dentro de la carpeta _CodeSignature.
  • Si la app contiene múltiples arquitecturas (por ejemplo, x86 y ARM), el proceso se repite por cada una de las arquitecturas soportadas.

Cuando el usuario hace doble-clic sobre la aplicación para ejecutarla, macOS realiza un proceso de verificación similar:

  • Recalcula el valor hash para cada uno de los archivos en el bundle.
  • Compara los valores recién calculados con los almacenados en la carpeta _CodeSignature y, en el caso de que alguno de ellos difiera del valor almacenado, macOS determina que el bundle ha sido modificado desde su firma y no ejecutará la app.

¿Quieres ver esto en acción? Crea un nuevo proyecto Desktop en el IDE de Xojo, guárdalo en la carpeta Documentos y haz clic sobre el botón Build para compilarla para macOS.

A continuación, ubica la app compilada en el Finder. Haz Control-Clic sobre su icono y elige la opción “Mostrar Contenidos del Paquete”. Luego, abre la carpeta Contents > _CodeSignature e inspecciona el archivo CodeResources utilizando para ello tu editor de textos favorito. Verás un listado correspondiente a los valores hash y los digest calculados para cada uno de los archivos en el bundle de la app.

Apple Developer Certificates: Estableciendo la Confianza en macOS

¿Qué has de hacer para que tus apps sean reconocidas como ciudadanos de primera clase en macOS y se puedan distribuir sin que Gatekeeper intervenga? La respuesta te sonará familiar: darte de alta en el Programa de Desarrolladores de Apple (unos US $99 anuales).

Entre las ventajas proporcionadas, la membresía en el Programa de Desarrolladores de Apple te permite crear los certificados Developer ID. Cuando utilizas estos certificados para firmar tus apps, macOS podrá validar la firma e identificarte como un desarrollador verificado cuando distribuyas tu software.

Pero, ¿cómo se establece dicha confianza y cómo se verifica? Para responderlo hemos de comenzar en la propia raíz del asunto, ¡literalmente!

Cada ordenador, teléfono inteligente, tableta y muchos, muchos otros dispositivos, se suministran de serie con Certificados Raíz preinstalados. Dichos certificados son emitidos por organizaciones confiables y verificadas denominadas Root Certificate Authorities (CAs), entre las cuales se encuentra Apple. Sirven como la base de una cadena de confianza, permitiendo así que los certificados emitidos por dichas autoridades puedan ser verificados.

Desde un punto de vista más técnico, una Root Certificate Authority (CA — Autoridad de Certificados Raíz) es una entidad de confianza de primer nivel en una infraestructura de clave pública (PKI, por sus siglas en inglés). Dichas entidades emiten certificados raíz autofirmados que actúan como un ancla de confianza durante el proceso de verificación de otros certificados digitales. En otras palabras, son los pilares sobre los que se asienta todo el modelo de confianza y validación de certificados.

Resulta sencillo echar un vistazo a los certificados raíz instalados en tu Mac:

  • Abre la app Acceso a Llaveros.
  • Selecciona Certificados en la parte superior de la ventana.
  • Selecciona Raíz del Sistema en la barra lateral.
  • Verás el listado completo correspondiente a los certificados raíz en los que confía macOS.

Observarás que hay tres certificados diferentes correspondientes a Apple Root CA. ¿Por qué?

Cada certificado X.509 contiene metadatos detallados que definen tanto sus propiedades criptográficas como el tipo de uso permitido. Esto incluye el tipo de clave (como puedan ser RSA o ECDSA), la longitud de la clave pública, y también el algoritmo de firma utilizado.

  • Apple Root CA: Su tipo es RSA con una longitud de clave pública de 2048 bits en el que se usa el algoritmo SHA-1.
  • Apple Root CA-G2: Su tipo es RSA con una longitud de clave pública de 4096 bits en el que se utiliza el algoritmo SHA-384.
  • Apple Root CA-G3: Su tipo es ECDSA con una longitud de clave pública de 384 bits en la que se utiliza el algoritmo SHA-384.

Certificados Intermedios y la Cadena de Confianza

Los Certificados Raíz son realmente valiosos y sensibles, de modo que en raras ocasiones se utilizan para firmar certificados emitidos a usuarios finales (también denominados certificados “Leaf” u hoja). En el caso del desarrollo de apps para macOS, los certificados de desarrollador tienen el rol de Leaf. Aquí es donde entran en juego los Certificados Intermedios.

En términos sencillos, los Certificados Intermedios son firmados por los Certificados Raís y, a su vez, se utilizan para firmar Certificados Leaf. Esto protege al certificado Raíz de una exposición directa. Juntos, los certificados Raíz, Intermedio y Leaf conforman lo que se denomina “Cadena de Confianza”.

La verificación sobre dicha Cadena de Confianza se inicia en el certificado que actúa como Leaf, y funciona hacia abajo sobre el certificado Intermedio y, por último, sobre el Raíz. Este mismo proceso es el que se realiza cada vez que visitas un sitio seguro, haces un pago en línea o bien transmites datos de forma segura.

Por ejemplo, el certificado Leaf se valida contra el certificado Intermedio. Si el certificado Intermedio no se encuentra o ha expirado, entonces el certificado Leaf se considera inválido. De igual modo, el certificado Intermedio se valida contra el certificado Raíz. Si el certificado Raíz no se encuentra o ha expirado, entonces el certificado Intermedio será inválido, al igual que todos los certificados Leaf emitidos (firmados) por dicho certificado Intermedio.

El mismo proceso ocurre cuando firmas tus apps macOS: macOS valida toda la cadena de confianza de los certificados antes de permitir la ejecución de la app.

Por último, los certificados más próximos a la Raíz tienen, por lo general, periodos de validez más amplios; mientras que los certificados Leaf han de renovarse con más frecuencia, y los certificados Raíz son los que cuentan con un periodo de vigencia mucho más amplios.

En resumen

En este primer artículo hemos cubierto los fundamentos relacionados con los certificados digitales y el papel que estos juegan la seguridad de las apps para macOS. En el próximo artículo nos centraremos específicamente en los certificados de Apple Developer y de cómo permiten la distribución confiable de aplicaciones.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *