首頁 > 軟體

python演演算法加密 pyarmor與docker

2022-06-21 14:09:54

前言

為了避免程式碼洩露的風險,我們往往需要對程式碼進行加密,PyArmor 是一個用於加密和保護 Python 指令碼的工具。它能夠在執行時刻保護 Python指令碼的二進位制程式碼不被洩露,設定加密後Python原始碼的有效期限,綁 定加密後的Python原始碼到硬碟、網路卡等硬體裝置。

一 基礎設定 安裝

pip install pyarmor

更新到最新版本:

pip install --upgrade pyarmor

二 基本語法 2.1 加密 Python 指令碼

a) 單個包,只有單級目錄

使用命令obfuscate來加密 python 指令碼。在最簡單的情況下,最常用的一種情況是切換到主函數指令碼algorithm.py所在的路徑,然後執行:

pyarmor obfuscate algorithm.py

PyArmor 會加密 algorithm.py 和相同目錄下面的所有 *.py 檔案:

  • 建立輸出子目錄 dist
  • 生成加密的主指令碼 algorithm.py 儲存在輸出目錄 dist
  • 加密相同目錄下其他所有 *.py 檔案,儲存到輸出目錄 dist
  • 生成執行加密指令碼所需要的全部輔助檔案,儲存到輸出目錄 dist

b) 若有多個演演算法包、多級目錄
預設情況下,只有和主指令碼相同目錄的其他 *.py 會被同時加密。如果想遞迴加密 子目錄下的所有 *.py 檔案,使用下面的命令:

pyarmor obfuscate --recursive algorithm.py

注意:只能加密.py檔案,如果演演算法需要呼叫.csv.json檔案,直接拷貝到dist資料夾對應的包裡就可以了

2.2 執行加密指令碼

執行加密指令碼不需要安裝pyarmo

cd dist
python algorithm.py

2.3 釋出加密指令碼

執行到這一步已經可以釋出加密指令碼了,釋出加密指令碼只需要把輸出路徑的所有dist檔案拷貝即可。

三、pyarmor&docker

由於pyarmo加密的指令碼對執行環境比較敏感,因此我們最好把整個演演算法打包成映象,在啟動容器的時候進行加密,並刪除所有的未加密檔案,留下dist檔案

注:上文也說過,pyarmo只能對.py檔案加密,對於.csv.json檔案是無法加密的,自然在生成的dist包裡也沒有非.py字尾的檔案,因此我們需要將.csv等檔案移入到dist裡,不然執行dist裡的演演算法時會報錯。

由於我本地是windows系統,所以生成.dll字尾檔案,直接把dist製作成映象會報錯,因為容器執行需要.so檔案,因此考慮在容器中執行時加密,生成.so,再自動移除未加密文鍵,只留下dist及所需的非.py字尾檔案,其實也可以用linux系統直接本地執行生成dist,但是不要忘記將非.py字尾的檔案及資料夾複製進去。

下面將以myprocessor的演演算法包為例,講述整個流程:

可以看出,裡面是多個演演算法包互相呼叫的,且有較多的非.py檔案

3.1 Dockerfile

FROM python:3.6 # 匯入python3.6基礎環境
RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
  && echo 'Asia/Shanghai'>/etc/timezone # 同步系統時間
COPY ./ ./app/ # 將演演算法裡面的所有檔案和資料夾複製到映象裡
WORKDIR /app/ # 設定映象裡的app為主資料夾
RUN pip3 install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple # 將演演算法需要的包在映象中進行安裝
RUN pyarmor obfuscate --recursive myprocessor.py # 對所有演演算法遞迴加密
RUN ls # 顯示app內的所有檔案
CMD ["python3","/app/dist/myprocessor.py"] # 執行dist內的加密後的主函數

3.2 requirements.txt

# 這裡就是執行我的演演算法依賴的模組,pyarmor==7.4.2一定要加,其他的根據自己的演演算法依賴新增
pyarmor==7.4.2
pandas == 1.1.5
numpy == 1.19.5
requests == 2.25.1

3.3 加密函數lock_by_pyarmor.py

# -*- coding: utf-8 -*- 
import shutil
import os
class File_lock():
    def __init__(self):
        self.root_path = os.getcwd()  # 當前工作路徑

    def remove_and_del_unsecret_dir_f(self):
        '''移除未加密的py和pyc檔案,複製非py,pyc檔案到dist'''
        for root, dir, files in os.walk(self.root_path):
            if "dist" not in root:
                for file in files:
                    if os.path.splitext(file)[-1] in ['.py', '.pyc']:
                        # 刪除所有未加密的.py和.pyc檔案
                        os.remove(os.path.join(root, file))
                    else:
                        # 由於非py檔案無法加密,因此將非py檔案移動到同名資料夾下,若找不到同名資料夾就建立同名資料夾
                        if root == self.root_path:
                            dist_same_die_path = os.path.join(self.root_path, 'dist')
                        else:
                            dist_same_die_path = os.path.join(self.root_path, 'dist', os.path.basename(root))
                        if not os.path.exists(dist_same_die_path):
                            os.mkdir(dist_same_die_path)
                        shutil.move(os.path.join(root, file), dist_same_die_path)

        temp_list = os.listdir() # 移除dist外的所有空資料夾
        temp_list.remove('dist')
        for i in temp_list:
            os.rmdir(i)

    def lock_by_pyarmor(self):
        # print("當前工作路徑:",self.root_path)
        # print("os.listdir", os.listdir())
        if (not os.path.exists(os.path.join(self.root_path, "dist"))):  # 若dist不存在
            os.system("pyarmor obfuscate --recursive myprocessor.py")  # 加密
            self.remove_and_del_unsecret_dir_f()
        else:
            # print("加密後資料夾:",os.listdir())
            self.remove_and_del_unsecret_dir_f()
            # print("移除未加密檔案後:",os.listdir())

3.4 主函數myprocessor.py

from lock_by_pyarmor import File_lock
def call(arg, model, *args, **kwargs):
    lockf = File_lock()
    lockf.lock_by_pyarmor()
    from deviation_algothrim.get_deviation import Deviation
    from loss_power.get_loss_power import GetPower
    pass
if __name__ == "__main__":

    print(call(arg=None, model=None))

注意:從其他包裡匯入需要的內容,需要放到lockf.lock_by_pyarmor()之後,不然,還沒有完全構建成dist檔案,可能會呼叫報錯。

3.5 建立映象並驗證效果

docker build _t imag1 .建立完映象後,app內目錄為:

  • docker run -d imag1 /bin/bash -c "tail -f /dev/null"
  • docker ps #找到正在執行的容器id
  • docker exec -it 2293ee92f3ca /bin/bash # 進入容器
  • python /app/dist/myprocessor.py # 執行加密檔案

可以看到app內只剩下了dist檔案。
最後需要將啟動的容器重新打包成映象,並行布到harbor上:docker commit 2293ee92f3ca7 new_image,丟棄原本的映象。因為原本映象中是有未加密檔案的,並且可以存取 。
可以將容器裡的加密檔案匯出到本地D槽: docker cp bf5f2e815b64:/app D:/

ps: 如有問題,或者lock_by_pyarmor.py有更好的實現方法,希望可以指正。

到此這篇關於python演演算法加密 pyarmor與docker的文章就介紹到這了,更多相關python 演演算法加密內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com