程式碼簽章

**代碼簽章**（英語：**Code signing**）是對可執行檔或程式碼進行數位簽章以確認軟體作者及保證軟體在簽章後未被修改或損壞的措施。此措施使用加密雜湊來驗證真實性和完整性。

代碼簽章可以提供幾大功能價值。最常用的需求是代碼簽章為部署提供了安全性。在某些程式語言中，它也可用來幫助防止命名空間衝突。幾乎每個代碼簽章的實現都提供某種數位簽章機制來驗證作者或構建系統的身分，以及校驗物件是否未被修改。它也可用來提供物件相關的版本資訊，以及儲存物件的其他元資料。

代碼簽章作為軟體安全性依賴的效果取決於所支援簽章金鑰的安全性。與其他公鑰基礎設施（PKI）技術一樣，系統的完整性依賴於發布者對其私鑰免受未經授權存取的保護。儲存在通用電腦的軟體中的金鑰易於受到影響。因此，將金鑰儲存在安全、防篡改的硬體密碼裝置（也稱硬體安全模組，HSM）是更加安全的最佳實踐。

## 安全保證

許多代碼簽章的實現提供方法來使用涉及一組金鑰的系統來簽章代碼，這類似 SSL 與 SSH 的流程。例如，在.NET 中，開發人員每次構建之時，都將使用一個私鑰來簽章自己的庫或可執行檔。此金鑰唯一且分屬給單個開發人員、小組，或者特定應用程式或實體。開發人員可以自己生成此金鑰，也可以從受信任的數位憑證認證機構（CA）取得一份金鑰。

代碼簽章在分發目的下很有價值，因為所提供代碼的原始碼可能並不明顯，如 Java applet、ActiveX 控制項或其他類似代碼。它的另一個重要用途是，為現有軟體安全地提供更新和修補程式。Windows、Mac OS X 和大多數 Linux 發行版為更新使用代碼簽章，從而確保其他人不可能通過修補程式系統分發惡意代碼。它可以使作業系統驗證更新是否合法，即使更新是由第三方或藉助物理媒介（如光碟、USB 隨身碟）分發。

在 Windows 和 Mac OS X 上，首次執行軟體時將檢查代碼簽章以驗證軟體的身分，確保軟體沒有被第三方分銷商或下載網站惡意篡改。因為平台的分散性，這種代碼簽章形式沒有在 Linux 上使用，軟體套件管理系統是所有軟體形式（不僅僅更新和修補程式）的主要發行模式，並且允許直接檢查原始碼的開放原始碼模型（如果需要）。

### 使用憑證頒發機構（CA）完成受信辨識

用於代碼簽章的公鑰應該可以追溯到受信任的根機構 CA，使用安全的公鑰基礎設施（PKI）是最佳做法。這雖不能保證代碼本身的可信，但可以確保它來自所聲明的來源（更明確來說，來自特定私鑰）。一個 CA 提供者可以提供根級別的信任，並能以代理方式將信任分配給其他人。如果使用者信任一個 CA，那麼使用者也相信該 CA 及其代理生成的金鑰所簽章的代碼合法性。許多作業系統和框架都內建對一個或多個現有 CA 的信任（例如 VeriSign/Symantec、DigiCert、TC TrustCenter、Comodo、GoDaddy 及 GlobalSign 等）。對大型組織來說，實現與公共 CA 功能相同但僅在組織內信任的私有 CA 也是常見的選擇。

### CA 的替代品

類似目的的另一種方式是 —— 開發人員可以使用自己生成的金鑰。在此種情況下，使用者首次通常必須直接從開發人員那裡取得公鑰，以便驗證物件的來源。許多代碼簽章系統將儲存簽章中的公鑰。部分軟體框架和作業系統將在執行前檢查代碼的簽章，並允許使用者選擇是否信任該開發者。應用程式開發者可以在安裝程式中包含公鑰以提供類似的系統。然後可以使用金鑰來確保需要執行的任何後續物件（例如升級、外掛程式或其他應用程式）都是來自同一開發人員。

### 時間戳

時間戳旨在解決憑證過期後開始出現的信任警告。在實際應用中，時間戳將使代碼的信任期延長到憑證有效期之後。

如果由於鑒權泄露或失效而必須復原憑證，則復原事件的具體時間將納入復原記錄。在這種情況下，時間戳有助於確認代碼是在憑證信任受損之前還是之後簽署。

### 問題

同任何安全措施一樣，代碼簽章也可以被擊破。使用者可能被誘騙而執行無簽章乃至拒絕被驗證的代碼，並且系統只能儘可能保持私鑰的安全性。

同樣重要的是，代碼簽章不會保護終端使用者免受軟體作者的惡意行為或無意破壞，而只是確認軟體未被作者以外的人修改。

## 實現

IBM 的 Lotus Notes 自第一版開始有一個 PKI 的代碼簽章，並且客戶端和伺服器軟體都有「執行控制列表」來控制指定使用者對資料、環境和檔案系統的存取級別。個別設計元素（栓指令碼、動作、代理等活動專案）始終使用編者的 ID 檔案來簽章，其中包括編者和域的公鑰。核心模板（如郵件模板）由 Lotus 模板開發團隊持有的專用 ID 簽章。

微軟公司為微軟測試的驅動程式提供了一種代碼簽章（基於 Authenticode）。因為驅動程式是在核心中執行，它們可能破壞系統的穩定性或者使系統出現安全漏洞。就此原因，微軟將測試提交到其 WHQL 計劃的驅動程式。在驅動程式通過測試後，微軟會將此版本的驅動程式標記為安全。在 32 位元系統上，安裝未通過微軟驗證的驅動程式可以在使用者被警告該代碼未被簽章時選擇允許安裝。對於.NET（代管）代碼來說，它有一種稱為強名稱簽章的額外機制，它採用公鑰 / 私鑰和 SHA-1 雜湊而不是憑證。不過，微軟不鼓勵用強名稱簽章來代替 Authenticode。

## 遊戲和消費裝置中的未簽章代碼

在諸如遊戲主機等消費者裝置語境中，未簽章代碼通常指一個未被通常必須有加密金鑰的應用程式接受和執行的軟體。大多數主機遊戲必須使用主機製造商設計的私鑰簽章，否則遊戲不會在主機上載入。使未簽章代碼被執行通常有幾種方法，包括軟體漏洞、使用 modchip、運用交換技巧技術，或者執行一個 softmod。

對於有簽章的應用程式複製到另一張 DVD 上就不能啟動的原因，通常不那麼顯而易見。在 Xbox 上，原因是 Xbox 可執行檔（XBE）包含一個媒體類型標誌，它指定了 XBE 可引導形式的媒體類型。對幾乎所有 Xbox 軟體來說，此設定使得可執行檔只能從工廠生產的光碟啟動，將可執行檔複製到可燒錄媒體上將終止軟體的可執行性。

但是，因為可執行檔本已簽章，因此僅更改標記值不可行，那將使可執行檔的簽章失效，從而在最初的驗證階段就檢查失敗。

## 互聯裝置的增長

伴隨著物聯網（IoT）增長的互聯裝置正成為代碼簽章的新需求。隨著越來越多的感測器和裝置被接入緊密的網路生態系統，憑證頒發機制已被擴充到人員辨識以外的機器辨識。與代碼簽章一樣，該技術使用數字證明確保了代碼的物理真實性和完整性，及在產品生命周期內隨時進行代碼的驗證與升級。這正為代碼簽章創造新的緯度：提高安全意識，以及需要在專用的保護環境中儲存私有簽章金鑰，為整個系統建立信任的根源。鑑於惡意軟體和進階持久威脅（APT）的流行，許多軟體供應商、線上服務提供商、企業 IT 組織和高科技 IoT 裝置的製造商都面臨著增加其高科技製造和代碼簽章過程安全性的壓力。

## 參見

* 數位簽章
* 越獄 (iOS)
* PlayStation Portable 破解
* 特權提升
* Root (Android)

## 參考資料

## 外部連結

* Apple Code Signing Guide
* Microsoft Introduction to Code Signing（頁面存檔備份，存於網際網路檔案館）
* Debian Security Infrastructure（頁面存檔備份，存於網際網路檔案館）
* Strong Name and Code Sign .Net assemblies with signIT! by Cove Bay Software（頁面存檔備份，存於網際網路檔案館）
* Strong Distribution HOWTO