Code signing: cum semnezi un binary și de ce contează
Code signing atașează o semnătură criptografică unui binary. OS-ul verifică autenticitatea sursei și integritatea fișierului înainte să-l ruleze.
Cuprins
- Ce este code signing mai exact?
- Cum funcționează lanțul de încredere (CA, certificat, cheie privată și binary)?
- Care sunt regulile pe macOS (notarization) și Windows (SmartScreen reputation)?
- Cât costă un certificat (EV vs OV vs IV) și de unde îl iei?
- Cum integrezi semnarea în CI fără să expui cheia privată (HSM, KMS și secrets vault)?
Code signing este procesul de atașare a unei semnături criptografice la un binar sau pachet de instalare, care permite sistemului de operare să verifice că fișierul vine de la un producător identificat și că nu a fost modificat de la semnare. Fără această semnătură, macOS și Windows tratează executabilele ca potențial periculoase și îi avertizează pe utilizatori înainte de rulare.
Procesul implică un certificat emis de o autoritate de certificare (CA), o cheie privată sub controlul exclusiv al dezvoltatorului și un binar care urmează să fie distribuit. Confuzia obișnuită este că semnarea ar garanta că un program este sigur; nu garantează. Garantează doar că fișierul nu a fost alterat după semnare și că semnătarul este cine pretinde că este.
Ce este code signing mai exact?
Code signing, sau semnarea codului, este un mecanism criptografic bazat pe infrastructura cu cheie publică (PKI). Aplicând semnătura, autorul confirmă două lucruri:
- Identitatea sursei. Certificatul leagă identitatea (o companie sau un dezvoltator individual verificat de CA) la o cheie publică. Oricine poate verifica că semnătura aparține acelui certificat.
- Integritatea conținutului. Semnătura acoperă hash-ul binarului. Dacă un singur byte se schimbă după semnare, semnătura devine invalidă.
Code signing acoperă executabile Windows (.exe, .dll), pachete macOS (.app, .pkg, .dmg), scripturi PowerShell, extensii de browser, firmware și, mai recent, container images și artefacte software (atestări Sigstore). Pentru aplicații desktop distribuite utilizatorilor finali, primele două categorii sunt cele mai relevante.
Cum funcționează lanțul de încredere (CA, certificat, cheie privată și binary)?
Fluxul standard la semnare are patru componente:
- CA (Certificate Authority). O organizație de încredere, recunoscută de sisteme de operare prin rădăcini de încredere pre-instalate. DigiCert, Sectigo, SSL.com, GlobalSign sunt CA-uri uzuale pentru code signing. Apple este propriul său CA pentru Developer ID.
- Certificatul. Un document digital semnat de CA care leagă identitatea ta verificată (denumire companie sau date individuale, după tipul certificatului) la cheia ta publică. Are o perioadă de valabilitate (de obicei un an) și un nivel de validare: EV (Extended Validation, cu verificare aprofundată a companiei), OV (Organization Validation) sau IV (Individual Validation).
- Cheia privată. Jumătatea secretă a perechii criptografice. Nu se distribuie niciodată; rămâne fie pe un hardware token, fie într-un HSM (Hardware Security Module), fie în serviciu de semnare gestionat. Semnarea se face prin aplicarea cheii private peste hash-ul binarului.
- Binarele. Hash-ul fișierului este semnat cu cheia privată. Semnătura și referința la certificat sunt încorporate în binar sau atașate separat. La rulare, OS-ul recalculează hash-ul, verifică semnătura cu cheia publică din certificat și validează că certificatul are un lanț de încredere valid până la o rădăcină recunoscută.
Un detaliu care surprinde: timestamp-ul de la momentul semnării trebuie inclus și el semnat de un server de timestamping (RFC 3161). Fără timestamp, semnătura devine invalidă la expirarea certificatului. Cu timestamp, binarele rămân valide chiar și după expirarea certificatului, dacă semnarea a avut loc în perioada lui de valabilitate.
Care sunt regulile pe macOS (notarization) și Windows (SmartScreen reputation)?
Cele două platforme principale au abordări diferite, dar ambele pedepsesc binarele nesemnate sau necunoscute.
macOS: Developer ID plus notarization. Apple emite certificatele Developer ID prin propriul program de dezvoltatori. Din macOS 10.15 Catalina, semnarea nu este suficientă: trebuie și notarizare. Trimiți binarele la Apple (prin notarytool) pentru analiză automată, primești o ștampilă (staple) și o incorporezi în binar. Fără notarizare, utilizatorul vede un mesaj de blocare chiar dacă binarele sunt semnate.
Windows: Authenticode plus SmartScreen. Pe Windows, semnezi cu Authenticode (signtool.exe din Windows SDK). SmartScreen, sistemul de reputație din Windows Defender, poate afișa „Windows a protejat PC-ul" pentru aplicații noi, indiferent dacă sunt semnate. Reputația se acumulează în zile sau săptămâni pe baza numărului de instalări. Un certificat EV sare peste această perioadă imediat, de aceea este preferat pentru aplicații noi fără bază de utilizatori.
Aplicațiile Tauri și alte aplicații desktop sunt direct afectate de aceste reguli la distribuție. Același subiect apare și în contextul OTA updates, unde pachetele de actualizare trebuie semnate individual înainte de distribuție.
Cât costă un certificat (EV vs OV vs IV) și de unde îl iei?
Există trei niveluri de validare, cu prețuri și cerințe diferite:
- IV (Individual Validation). Verifică identitatea unui individ, nu a unei companii. Cel mai rapid de obținut (zile). Costă în jur de 100-300 USD pe an. Util pentru dezvoltatori independenți; nu acordă reputație SmartScreen imediată.
- OV (Organization Validation). Verifică existența legală a companiei. Procesul durează câteva zile și cere documente juridice. Costă în jur de 200-500 USD pe an. Standard pentru aplicații distribuite de companii.
- EV (Extended Validation). Cel mai strict nivel de verificare, cu audit fizic al companiei. Costă în jur de 300-800 USD pe an, plus un hardware token USB obligatoriu (cheia EV nu poate fi exportată din token). Singurul tip care acordă reputație SmartScreen imediată.1
Furnizorii principali: DigiCert, Sectigo, SSL.com, GlobalSign. Prețurile variază; cumpărarea prin revânzători autorizați poate fi mai ieftină decât direct. Pe macOS, Developer ID-ul Apple se obține prin Apple Developer Program (99 USD pe an per cont, indiferent de numărul de aplicații).
Cum integrezi semnarea în CI fără să expui cheia privată (HSM, KMS și secrets vault)?
Semnarea manuală, locală, a binarelor la fiecare release creează dependențe: depinzi de mașina unui singur developer, iar cheia poate fi pierdută dacă se strică discul sau pleacă omul. Integrarea în pipeline-ul de Continuous Integration este mai sigură dacă este făcută corect.
Principiul de bază: cheia privată nu trebuie să fie niciodată pe mașina de build sau în variabile de mediu accesibile dezvoltatorilor. Opțiunile practice:
- Servicii de semnare gestionată. DigiCert KeyLocker, SSL.com eSigner sau Azure Trusted Signing stochează cheia în HSM-ul lor. CI-ul trimite hash-ul binarului la API; serviciul aplică semnătura și returnează binarele semnate. Cheia nu traversează niciodată infrastructura ta. Prețul: câțiva USD per semnătură sau abonament lunar.
- Azure Key Vault Managed HSM sau AWS CloudHSM. Cheia privată este stocată în HSM-ul platformei cloud. Poți folosi extensii de pipeline (ex: Azure DevOps extension pentru Key Vault) care semnează binarele direct prin Key Vault API. Accesul este controlat prin politici IAM și jurnalizat complet.
- Hardware token izolat pe mașina de build dedicată. Token-ul USB EV este conectat fizic la un server de build dedicat, izolat de rețea. CI-ul se conectează la acel server prin agent. Opțiunea obișnuită pentru echipe fără cloud, dar cere că serverul să fie securizat fizic.
Anti-patternele clasice de evitat:
- Cheia privată în repozitoriu git. Inclusiv în ramuri vechi sau în istoricul git. Odată acolo, cheia trebuie revocată.
- Cheia privată în secrets neprotejate suplimentar. Un secret GitHub Actions sau GitLab CI neprotejat prin environment-level restrictions este accesibil oricărui workflow din repo. Restricționează secretele la environment-uri protejate cu aprobare manuală pentru release-uri.
- Cheia exportată ca .p12 distribuit pe mai mulți developeri. Fiecare copie este o suprafață de atac suplimentară. Dacă un laptop e furat sau compromis, trebuie revocat tot.
Semnarea corectă în CI urmează același principiu ca gestionarea oricărui secret critic: cheia nu stă în cod, accesul este jurnalizat, iar sursa de adevăr este un sistem dedicat. La crawlerra, secretele critice de producție sunt stocate în Vaultwarden (self-hosted), cu acces limitat la operatorul de build, același tipar descris și pentru JWT-urile stocate separat de cod. Pașii de semnare la release aparțin explicit runbook-ului de release, nu memoriei individuale. Alertarea pe build și deploy este parte din observabilitate la nivel de pipeline.
- Prețurile sunt orientative la data redactării (2026) și variază între furnizori și geografii. Verifică direct la DigiCert, Sectigo sau SSL.com pentru cotații actualizate.
Întrebări frecvente
Am nevoie de un certificat EV sau e suficient unul OV?
Depinde de platforma țintă. Pe macOS, tipul certificatului (Developer ID) este fix și emis exclusiv de Apple prin programul Developer. Pe Windows, un certificat OV sau IV îți permite să semnezi, dar SmartScreen va afișa avertisment până când binarele tale acumulează suficient volum de instalări. Un certificat EV sare peste această perioadă imediat, de aceea e preferat pentru utilitare care nu au bază de utilizatori în prealabil.
Ce se întâmplă dacă distribui un binar nesemnat pe macOS?
Gatekeeper blochează execuția și afișează un mesaj care spune că aplicația nu poate fi verificată. Utilizatorul poate ocoli blocajul din System Settings, dar este un obstacol serios în adoptare. Pentru distribuție în afara Mac App Store, Developer ID plus notarization sunt practic obligatorii din macOS 10.15 Catalina.
Cât costă un certificat de code signing?
Un certificat OV sau IV costă între 200 și 500 USD pe an; un certificat EV costă între 300 și 800 USD pe an. Furnizorii principali sunt DigiCert, Sectigo, SSL.com și GlobalSign. Certificatele EV cer și un hardware token fizic (USB), deoarece cheia privată nu poate fi exportată din el.
Pot păstra cheia privată în GitHub Actions secrets?
Poți exporta un certificat software ca fișier .p12 și stoca parola în secrets, dar nu este opțiunea cea mai sigură. O alternativă mai solidă este să folosești un serviciu de semnare la distanță (Azure Trusted Signing, AWS Signer, DigiCert KeyLocker) unde cheia rămâne pe server și CI-ul trimite hash-ul pentru semnare. Cheia nu traversează niciodată pipeline-ul.
Notarizarea pe macOS este obligatorie?
Nu obligatorie prin lege, dar practic obligatorie pentru orice aplicație distribuită utilizatorilor finali. Fără notarizare, Gatekeeper blochează rularea pe macOS 10.15 și versiunile ulterioare. Notarizarea este un pas suplimentar față de semnare: trimiți binarele la Apple pentru analiză automată și primești o ștampilă care este încorporată în binar (stapling).