Python 轉 exe 執行檔並進行程式簽章
前言
最近在將 Python 程式轉成 Windows 執行檔給同事時,發現會一直被系統防毒軟體判定為病毒,這造成我們蠻大的困擾。
後來經過查詢發現這跟程式中所使用的 Library 有非常大的關聯性,為了避免這個問題,可以考慮使用 Code Signing 透過可信任憑證授權中心 (CA) 來減少安全性警告,但是一般來說 Code Signing 必需要以「公司名義」向微軟認可的發行商購買,且具有使用期限,價格也不斐,對於個人開發者來說是一筆非常龐大的負擔,所幸在台灣有一個自然人憑證 IC 卡,他可以用來作為網路資料交換時,做為身份識別與驗證,而這個「自然人憑證」包含了「數位簽章」及「公開金鑰」,而其中的數位簽章是經過 Windows 所認可的,也就是說我們可以用此數位簽章作為一個 Code Signing,用自己的名字為自己寫的程式作為一個背書,確認自己是檔案的發行者,藉此獲得 Windows 的認可,接下來會說明怎麼使用自然人憑證進行 Code Signing。
Python 打包成執行檔
目前對 Python 代碼打包成執行檔的方式常用的有四種方法(bbFreeze已停止維護,就此忽略它)。
Solution | Windows | Linux | OSX | Python3 | License | One-file mode | Zipfile import | Eggs | pkg_resources support | Latest release date |
---|---|---|---|---|---|---|---|---|---|---|
py2exe | yes | no | no | yes | MIT | yes | yes | no | no | Nov 17, 2021 |
pyInstaller | yes | yes | yes | yes | GPL | yes | no | yes | no | Nov 10, 2021 |
cx_Freeze | yes | yes | yes | yes | PSF | no | yes | yes | no | Nov 29, 2021 |
py2app | no | no | yes | yes | MIT | no | yes | yes | yes | Sep 27, 2021 |
資料來源:The Hitchhiker’s Guide to Python, Update the latest release date on 2021/12/2
我個人比較常用的是 PyInstaller,關於各種方法使用比較可以參考 Python 打包 EXE 方法匯總整理, 在這裡我就不多做著墨,大家依照自己的需求做選擇。
PyInstaller 安裝方法
1 | # 透過 pip 安裝 Pyinstaller |
PyInstaller 打包方式
安裝完成後,這邊先簡單紀錄最常用的指令,想知道進階指令可以到 pyinstaller -h
去查詢。
整個 PyInstaller 簡易指令架構如下,需要注意指令的大小寫。
1 | pyinstaller [功能指令] [python script 檔案位置] [-n NAME] [-c] [-i] |
縮寫指令 | 完整指令 | 說明 |
---|---|---|
-F | –onefile | 將所有檔案資料打包成單一 exe 執行檔 |
-D | –onedir | 將所有的東西打包成一個資料夾(包含多個引用資源)其中的含括 exe 執行檔 |
–specpath | N/A | 輸出檔案到指定路徑或資料夾 |
-n Name | –name Name | 打包的檔名,如果省略該選項,那麼第一個指令碼的主檔名將作為 exe 執行檔的命名 |
-w | –windowed –noconsole |
指定程式執行時不顯示命令列視窗,僅針對 Windows 和 Mac OS X 有效 |
-c | –console –nowindowed |
指定程式執行使用命令列視窗,默認模式 |
-i | 設置執行檔的圖示,需為 .ico 檔,預設為 NONE ,其他進階應用請參見 pyinstaller -h |
在未指定輸出路徑狀態下,請先確認自己的 Terminal 路徑位置是在哪,預設轉換好的文件會放置在 Terminal 指令路徑下。
如下圖所示,打包好的文件會直接放置在 ~/Documents/02_Program/GitHub/test
,這是蠻多第一次使用的人沒有注意到的地方。
PyInstaller 生成檔案
-F 模式
1 | pyinstaller -F /Users/Documents/02_Program/GitHub/test/test.py |
test.py
會生成檔案如下
1 | . |
檔案 | 說明 |
---|---|
build 資料夾 | 編譯過程的產物;後續可以刪除。 |
dist 資料夾 | 放置編譯結果,所有編譯完成需要的檔案都在這裡,其中包含我們需要的 exe 執行檔 |
test.spec | 根據使用者針對 Pyinstaller 有使用到的功能,整理成.spec 檔;後續可以刪除。 |
-D 模式
1 | pyinstaller -D /Users/Documents/02_Program/GitHub/test/test.py |
test.py
會生成檔案如下
1 | . |
由上述產生的檔案清單進行比較,可以看出兩者之間的差異。
自然人憑證簽章事前準備
接下來我們需要針對編譯完成的「.exe
執行檔進行簽章」,在使用自然人憑證簽章前,需要先準備以下幾個工具。
- 自然人憑證 IC 卡
請至戶政事務所辦理(不包含各地民政局(處))。 - IC 卡讀卡機
因為自然人憑證不像一般的 Code Signing 可以轉匯出 PFX 憑證,所以每次執行時都需要使用讀卡機用 IC 卡簽署。 - 安裝自然人憑證「ICOS 卡片管理工具」
請至內政部憑證管理中心下載,此為自然人憑證 PIN 碼驗證簽章與加解密功能檢測程式。 - 安裝 Visual Studio
需要使用 Visual Studio 內含的 Signtool 命令列工具,請至 Microsoft 下載。
如果不像安裝 Visual Studio,也可以上網搜尋網友分離出來的 Signtool 進行使用。
進行程式碼簽章作業
在執行簽章作業前,請先確認工作列是否已經執行了「ICOS 卡片管理工具」。
開啟 Visual Studio 的 「Developer PowerShell for VS」,這裡要特別注意,在沒有設置
PATH
狀況下使用 PowerShell 或 Windows Terminal 會造成 Signtool 執行失敗,為了簡化設置流程,建議直接使用 Visual Studio 的 「Developer PowerShell for VS」即可。接下來我們可以直接執行簽章作業,可以參考下列範例指令。
1
signtool sign /a /t http://timestamp.sectigo.com /v C:\Users\Desktop\test\test.exe
語法對照
1
signtool [command] [options] [file_name | ...]
以下稍微說明這些指令的意義,需要注意指令的大小寫,進階指令可以至 Microsoft 查詢。
引數 說明 sign
數位簽署檔案。 數位簽章可以防止檔案遭到篡改,而且可讓使用者根據簽署憑證確認簽署者。 /a
自動選取最佳的簽署憑證。 簽署工具會找到滿足所有指定條件的所有有效憑證,並且選取有效時間最長的一個。 如果沒有這個選項,簽署工具只需要找出一個有效的簽署憑證。 /t
URL指定時間戳記伺服器的 URL。 如果沒有這個選項,簽署的檔案就不會加上時間戳記。 如果加上時間戳記失敗,便會產生警告。範例中的 http://timestamp.sectigo.com,是時間戳記伺服器的 URL。 /v
不論命令執行成功或失敗,都顯示詳細資訊輸出,並顯示警告訊息。 /u
指定為加入的目錄檔自動產生一個唯一的名稱。 必要時,目錄檔會重新命名,以避免與現有的目錄檔發生名稱衝突。 如果沒有指定這個選項,簽署工具會覆寫具有與所要加入之目錄相同名稱的所有現有目錄。 執行指令後,會跳出輸入自然人憑證 Pin 碼視窗,請輸入自然人憑證 IC 卡的 PIN 碼。
當程式執行完後,會顯示以下狀態,來顯示程式簽署的狀況,
Number of files successfully Signed
代表完成簽署的文件數量。1
2
3Number of files successfully Signed: 1
Number of warnings: 0
Number of errors: 0當簽署完後,可以直接檔案的「內容」去查看簽署的狀況。
以上就完成整個簽章流程,這個程式就將會是以你的名字作為背書,這樣應該就可解決讓防毒軟體造成誤判的問題呢!~