La firma de código es el proceso de firmar digitalmente archivos ejecutables y scripts para confirmar el autor del software y garantizar que el código no haya sido alterado o dañado desde que fue firmado. El proceso emplea el uso de un hash criptográfico para validar la autenticidad e integridad. [1] La firma de código fue inventada en 1995 por Michael Doyle, como parte del complemento del navegador Eolas WebWish, que permitió el uso de criptografía de clave pública para firmar el código del programa de la aplicación web descargable utilizando una clave secreta, de modo que el intérprete de código del complemento pudiera usar la clave pública correspondiente para autenticar el código antes de permitirle el acceso a las API del intérprete de código. [2]
La firma de código puede proporcionar varias funciones valiosas. El uso más común de la firma de código es brindar seguridad durante la implementación; en algunos lenguajes de programación, también se puede utilizar para ayudar a prevenir conflictos de espacios de nombres. Casi todas las implementaciones de firma de código proporcionarán algún tipo de mecanismo de firma digital para verificar la identidad del autor o el sistema de compilación, y una suma de comprobación para verificar que el objeto no haya sido modificado. También se puede utilizar para proporcionar información de versiones sobre un objeto o para almacenar otros metadatos sobre un objeto. [3]
La eficacia de la firma de código como mecanismo de autenticación para software depende de la seguridad de las claves de firma subyacentes. Al igual que con otras tecnologías de infraestructura de clave pública (PKI) , la integridad del sistema depende de que los editores aseguren sus claves privadas contra el acceso no autorizado. Las claves almacenadas en software en computadoras de uso general son susceptibles de ser comprometidas. Por lo tanto, es más seguro y la mejor práctica es almacenar las claves en dispositivos de hardware criptográficos seguros y a prueba de manipulaciones, conocidos como módulos de seguridad de hardware o HSM . [4]
Muchas implementaciones de firma de código proporcionarán una forma de firmar el código utilizando un sistema que involucra un par de claves, una pública y una privada, similar al proceso empleado por TLS o SSH . Por ejemplo, en el caso de .NET, el desarrollador utiliza una clave privada para firmar sus bibliotecas o ejecutables cada vez que compila. Esta clave será única para un desarrollador o grupo o, a veces, por aplicación u objeto. El desarrollador puede generar esta clave por su cuenta u obtener una de una autoridad de certificación (CA) de confianza. [5]
La firma de código es particularmente valiosa en entornos distribuidos, donde la fuente de un fragmento de código determinado puede no ser evidente de inmediato; por ejemplo, applets de Java , controles ActiveX y otros códigos de scripts activos para navegadores y web. Otro uso importante es proporcionar actualizaciones y parches de forma segura al software existente. [6] Windows , Mac OS X y la mayoría de las distribuciones de Linux proporcionan actualizaciones mediante la firma de código para garantizar que no sea posible que otros distribuyan código de forma maliciosa a través del sistema de parches. Permite que el sistema operativo receptor verifique que la actualización es legítima, incluso si la actualización fue entregada por terceros o medios físicos (discos). [7]
La firma de código se utiliza en Windows y Mac OS X para autenticar el software en la primera ejecución, lo que garantiza que el software no haya sido manipulado maliciosamente por un distribuidor externo o un sitio de descarga. Esta forma de firma de código no se utiliza en Linux debido a la naturaleza descentralizada de esa plataforma, ya que el administrador de paquetes es el modo predominante de distribución para todas las formas de software (no solo actualizaciones y parches), así como el modelo de código abierto que permite la inspección directa del código fuente si se desea. Las distribuciones de Linux basadas en Debian (entre otras) validan los paquetes descargados utilizando criptografía de clave pública. [8]
La clave pública utilizada para autenticar la firma del código debe poder rastrearse hasta una autoridad raíz de confianza (CA), preferiblemente utilizando una infraestructura de clave pública (PKI) segura. Esto no garantiza que se pueda confiar en el código en sí, solo que proviene de la fuente indicada (o más explícitamente, de una clave privada particular ). [9] Una CA proporciona un nivel de confianza raíz y puede asignar confianza a otros por proxy. Si un usuario confía en una CA, entonces el usuario presumiblemente puede confiar en la legitimidad del código que está firmado con una clave generada por esa CA o uno de sus proxies. Muchos sistemas operativos y marcos contienen confianza incorporada para una o más autoridades de certificación. También es común que las grandes organizaciones implementen una CA privada, interna a la organización, que proporciona las mismas características que las CA públicas, pero solo es confiable dentro de la organización.
Los certificados de firma de código con validación extendida (EV) están sujetos a requisitos técnicos y de validación adicionales. Estas pautas se basan en los Requisitos básicos y las Pautas de validación extendida del CA/B Forum. Además de los requisitos de validación específicos para EV, las pautas de firma de código EV estipulan que "la clave privada del suscriptor se genera, almacena y utiliza en un módulo criptográfico que cumple o supera los requisitos de FIPS 140-2 nivel 2". [10]
Algunas aplicaciones, como la firma de controladores en modo kernel de Windows 10, requieren un certificado de firma de código EV. [11] Además, el IEBlog de Microsoft afirma que los programas de Windows "firmados por un certificado de firma de código EV pueden establecer inmediatamente una reputación con los servicios de reputación SmartScreen incluso si no existe una reputación previa para ese archivo o editor". [12]
Este es un ejemplo de un certificado de firma de código EV decodificado que SSL.com utiliza para firmar software. SSL.com EV Code Signing Intermediate CA RSA R3
se muestra como el nombre común del emisor, lo que lo identifica como un certificado de firma de código EV. El Subject
campo del certificado describe a SSL Corp como una organización. Code Signing
se muestra como el único uso de clave extendida X509v3.
Certificado: Datos: Versión: 3 (0x2) Número de serie: 59:4e:2d:88:5a:2c:b0:1a:5e:d6:4c:7b:df:35:59:7d Algoritmo de firma: sha256WithRSAEncryption Editor: commonName = SSL.com Firma de código EV Intermedio CA RSA R3 nombreOrganización = SSL Corp nombreDeLocalidad = Houston nombreDeEstadoOProvincia = Texas nombre_pais = US Validez No antes: 30 de agosto de 2019, 20:29:13 GMT No después del 12 de noviembre de 2022, 20:29:13 GMT Sujeto: 1.3.6.1.4.1.311.60.2.1.3 = EE. UU. 1.3.6.1.4.1.311.60.2.1.2 = Nevada Dirección de la calle = 3100 Richmond Ave Ste 503 businessCategory = Organización privada Código postal = 77098 nombrecomún = SSL Corp Número de serie = NV20081614243 nombreOrganización = SSL Corp nombreDeLocalidad = Houston nombreDeEstadoOProvincia = Texas nombre_pais = US Información de clave pública del sujeto: Algoritmo de clave pública: rsaEncryption Clave pública: (2048 bit) Módulo: 00:c3:e9:ae:be:d7:a2:6f:2f:24 ... Exponente: 65537 (0x10001) Extensiones X509v3: Identificador de clave de autoridad X509v3: ID de clave:36:BD:49:FF:31:2C:EB:AF:6A:40:FE:99:C0:16:ED:BA:FC:48:DD:5F Acceso a la información de la autoridad: Emisores de CA - URI: http://www.ssl.com/repository/SSLcom-SubCA-EV-CodeSigning-RSA-4096-R3.crt OCSP - URI: http://ocsps.ssl.com Políticas de certificación X509v3: Política: 2.23.140.1.3 Política: 1.2.616.1.113527.2.5.1.7 Política: 1.3.6.1.4.1.38064.1.3.3.2 Base de datos de recursos: https://www.ssl.com/repository Uso extendido de la clave X509v3: Firma de código Puntos de distribución de CRL X509v3: Nombre completo: Dirección URL: http://crls.ssl.com/SSLcom-SubCA-EV-CodeSigning-RSA-4096-R3.crl Identificador de clave de sujeto X509v3: CE:6A:64:06:26:A7:7A:69:E8:CC:06:D5:6F:FA:E1:C2:9A:29:79:DE Uso de la clave X509v3: crítico Firma digital Algoritmo de firma: sha256WithRSAEncryption 17:d7:a1:26:58:31:14:2b:9f:3b ...
El otro modelo es el de confianza en el primer uso , en el que los desarrolladores pueden optar por proporcionar su propia clave autogenerada. En este escenario, el usuario normalmente tendría que obtener la clave pública de alguna manera directamente del desarrollador para verificar que el objeto proviene de él por primera vez. Muchos sistemas de firma de código almacenarán la clave pública dentro de la firma. Algunos marcos de software y sistemas operativos que verifican la firma del código antes de ejecutarlo le permitirán elegir confiar en ese desarrollador a partir de ese momento después de la primera ejecución. Un desarrollador de aplicaciones puede proporcionar un sistema similar al incluir las claves públicas con el instalador. La clave se puede utilizar luego para garantizar que todos los objetos posteriores que se necesiten ejecutar, como actualizaciones, complementos u otra aplicación, se verifiquen como provenientes del mismo desarrollador.
El sellado de tiempo fue diseñado para evitar la advertencia de confianza que aparecerá en el caso de un certificado vencido. En efecto, el sellado de tiempo extiende la confianza del código más allá del período de validez de un certificado. [13]
En caso de que un certificado deba ser revocado debido a una vulneración, la fecha y hora específicas del evento comprometedor pasarán a formar parte del registro de revocación. En este caso, el sellado de tiempo ayuda a determinar si el código se firmó antes o después de que el certificado se viera comprometido. [13]
Los desarrolladores deben firmar sus aplicaciones iOS y tvOS antes de ejecutarlas en cualquier dispositivo real y antes de subirlas a la App Store . Esto es necesario para demostrar que el desarrollador posee un ID de desarrollador de Apple válido. Una aplicación necesita un perfil o certificado válido para poder ejecutarse en los dispositivos. [14]
Como cualquier medida de seguridad, la firma de código puede ser burlada. Se puede engañar a los usuarios para que ejecuten código no firmado, o incluso para que ejecuten código que se niega a validarse, y el sistema solo permanece seguro mientras la clave privada siga siendo privada. [15] [16]
También es importante tener en cuenta que la firma de código no protege al usuario final de ninguna actividad maliciosa o errores de software no intencionales por parte del autor del software; simplemente garantiza que el software no haya sido modificado por nadie más que el autor. A veces, los sistemas sandbox no aceptan certificados debido a una marca de tiempo falsa o debido a un uso excesivo de RAM .
Microsoft implementa una forma de firma de código (basada en Authenticode) proporcionada para los controladores probados por Microsoft. Dado que los controladores se ejecutan en el núcleo, pueden desestabilizar el sistema o abrirlo a agujeros de seguridad. Por esta razón, Microsoft prueba los controladores enviados a su programa WHQL . Una vez que el controlador ha pasado la prueba, Microsoft firma esa versión del controlador como segura. Solo en sistemas de 32 bits, es posible instalar controladores que no estén validados con Microsoft después de aceptar permitir la instalación en un mensaje que advierte al usuario que el código no está firmado. Para el código .NET (administrado), existe un mecanismo adicional llamado Firma de nombre fuerte que utiliza claves públicas/privadas y hash SHA -1 en lugar de certificados. Sin embargo, Microsoft desaconseja la confianza en la Firma de nombre fuerte como reemplazo de Authenticode. [17]
El Grupo de Trabajo de Firma de Código del Foro CA/Navegador decidió que a partir del 1 de junio de 2023, todos los certificados de firma de código (no solo los de EA) deberían exigir el almacenamiento de la clave privada en un medio físico, como en un módulo criptográfico de hardware que cumpla al menos con FIPS 140-2 Nivel 2 o Common Criteria EAL 4+. [18] Posteriormente, las CA emitieron anuncios sobre el cumplimiento de la decisión. [19] [20] [21] [22] [23] [24] [25]
En el contexto de los dispositivos de consumo, como las consolas de juegos , el término "código no firmado" se utiliza a menudo para referirse a una aplicación que no ha sido firmada con la clave criptográfica que normalmente se requiere para que el software sea aceptado y ejecutado. La mayoría de los juegos de consola tienen que estar firmados con una clave secreta diseñada por el fabricante de la consola o el juego no se cargará en la consola (tanto para imponer la dependencia del proveedor como para combatir la piratería de software). Hay varios métodos para lograr que se ejecute el código no firmado, que incluyen exploits de software , el uso de un modchip , una técnica conocida como el truco del intercambio o la ejecución de un softmod .
Puede que al principio no parezca obvio por qué el simple hecho de copiar una aplicación firmada en otro DVD no permite que arranque. En la Xbox , la razón es que el archivo ejecutable de Xbox (XBE) contiene un indicador de tipo de medio, que especifica el tipo de medio desde el que se puede arrancar el XBE. En casi todo el software de Xbox, esto está configurado de tal manera que el ejecutable solo arrancará desde discos producidos de fábrica, por lo que simplemente copiar el ejecutable en un medio grabable es suficiente para detener la ejecución del software.
Sin embargo, dado que el ejecutable está firmado, no es posible simplemente cambiar el valor del indicador ya que esto altera la firma del ejecutable y provoca que falle la validación cuando se verifica.
(Sección 1.2.2) [...] A partir del 1 de junio de 2023, para los certificados de firma de código, las CA DEBEN garantizar que la clave privada del suscriptor se genere, almacene y utilice en un módulo criptográfico de hardware adecuado que cumpla o supere los requisitos especificados en la sección 6.2.7.4.1 utilizando uno de los métodos de 6.2.7.4.2.