如何保護你的 Python 腳本

Posted by Mr. D-Day

對於很多程式開發者,腳本語言(Script Language)應該是蠻常見的,諸如 shell script、JavaScript、Perl、PHP、Ruby 等。腳本語言的執行方式是動態的,也就是說原始碼原則上是不需要先經過編譯的。這對於一些商業用途的產品會產生一點困擾,因為這意謂著,產品必須以原始碼型態的方式發佈。除了原始碼,包含一些產品運作必須的重要參數,例如:資料庫密碼,也都會用明碼的方式存在。

對於 PHP 來說,像是 ionCubeSourceGuardianphpSHIELD 等商業化軟體都可以幫助我們解決這個窘境。如果是 Python 呢?以下是我知道的幾種作法:

把原始碼轉成 pyc 檔

我想這應該是每個 Python Programmer 最先想到的方法。因為 Python 在執行時,最先把 Python 原始碼轉變為易於執行的 bytecode,也就是 .pyc  檔。這些 .pyc 檔都是一些二進碼,並不利於人類閱讀,所以作拿來保護原始碼聽起來很適合。但是很可惜,.pyc 的decompiler (反編譯)工具算蠻成熟的,例如 Easy Python Decompiler

包裝成一個執行檔

雖然 Python 是一個跨平台語言,但這並不表示每台電腦或伺服器都安裝了 Python 直譯器,特別是個人用戶。因此有時候產品發行的時候,會希望使用像 Py2ExePyInstaller 這類型的工具,把 Python 直譯器與原始碼統一包成一個單一執行檔,使用者只要用像執行一般程式一樣的方式執行,也不用管環境有沒有安裝 Python 直譯器。也因為包裝後,看起來純粹就是一個執行檔,所以這類工具也可以被拿來當成 Python 原始碼保護使用。

打亂原始碼(obfuscation)

把 Python 原始碼打亂是另一種可行之道。被打亂的原始碼原則上還是一個符合 Python 語法的程式,只不過可能因為少了空白、換了變數名稱、或寫作方式,導致一般程式設計者很難閱讀。這種方式在 JavaScript 是很常見的,因為 obfuscatinon 通常附帶的好處是「減少程式碼的大小」。例如:pyminifier 就是屬於這類型的工具。

更改 bytecode 定義表

前面提到的方式都是比較容易的作法,但是嚴格講起來,並沒有辦法很確實的保護原始碼。像 Dropbox 為了實現跨平台的資料同步,它們所提供的資料同步程式,是以 Python 為基礎做開發的。為了保護自己的產品,Dropbox 乾脆修改了 Python 直譯器,開發自有的保護機制。簡明扼來說,Dropbox 的保護機制是以 Python 的 bytecode 為基礎,但是它更改了幾個 bytecode 機器碼的對應表(bytecode re-mapping),這導致你無法使用一般標準的 Python 直譯器執行它的程式,也無法透過像 Easy Python Decompiler 這樣的工具把程式反組譯回來。有興趣仔細研究的讀者,可以參考這篇文章

直接加密原始碼

這種作法是先把原始碼加密後發佈,只有在執行的時候,才會把加密的原始碼還原來執行。它與 Dropbox 採用的方式有著一樣的特點,就是必須採用客製化的 Python 直譯器,而不能直接在標準的 Python 環境底下執行。但是比起前面三種方式,因為執行時期,所有的原始碼都要多經過一道解碼的手續,對於執行效率要求比較高的應用或許可能會有一點影響。例如:PyProtect 算是屬於這一類的作法的工具。

喜歡這篇文章嗎? 分享出去給作者一點鼓勵吧!