網站首頁 編程語言 正文
前言
深度學習領域,常常用python寫代碼,而且是建立在一些開源框架之上,如pytorch。在實際的項目部署中,也有用conda環境和python代碼去部署服務器,在這個時候,又分為兩種情況。
部署方式可分為兩種,一種是在線部署,算法服務器歸公司所有,只開放API給客戶,客戶通過POST請求訪問算法服務器,上傳數據并得到返回結果。這種情況客戶當然看不到代碼。還有一種是離線部署,就是給客戶私有化部署,把公司的代碼放到客戶的服務器上運行,這種情況下客戶能夠看到代碼。如果是python部署的項目,就需要保護兩個東西,一個是模型文件,一個是python源代碼。
一、python源代碼的保護
由于 Python 的動態特性和開源特點,導致 Python 代碼很難做到很好的加密。在實際工程部署中,如果不想讓客戶看到代碼,一般使用C++來部署。
可是自己把代碼改成c++也太費勁了,還好python提供了轉c++代碼的工具cpython,代碼轉成c++之后,編譯成.so(linux)的庫文件,就完成了加密效果了。整個過程已經有人寫好了響應的工具,如jumy,具體參考:GitHub - Boris-code/jmpy: python 代碼加密|加固
使用之前先安裝jumy
pip install jmpy3
然后找到找到項目目錄,在當前打開終端,并執行下面命令就能夠完成編譯。
jmpy -i "xxx project dir" [-o output dir]
加密后的文件默認存儲在 dist/project_name/ 下。注意工程文件夾下,凡是帶有if __name__=="__main__"的只要存在都不編譯,注釋掉一樣不編譯。其他的py文件才編譯。所以在使用時可以把main文件暴露出來,其他的文件都編譯成了.so的庫文件。
優點:.so文件為二進制文件,無法反編譯出源代碼,源碼可以得到有效保護。
缺點:編譯過程會編譯一些底層的代碼進去,如python版本之類的,所以編譯后的工程依舊依賴于環境,不能把其他機器上編譯好的文件直接拿過去用。
二、pytorch模型.pth的加密
對于一個文件的加密其實還是容易,這里我們用AES(一種對稱加密算法)對模型文件進行加密。
首先要安裝一個包,里面包含很多加密算法,ubuntu上安裝命令為‘
pip install pycrypto
然后寫一個python腳本,實現讀取模型文件,加密后保護的功能,和讀取加密文件,解密后保存的功能。
from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex
# 如果text不足16位的倍數就用空格補足為16位
def add_to_16(text:bytes):
if len(text) % 16:
add = 16 - (len(text) % 16)
else:
add = 0
text = text + (b'\0' * add)
return text
# 加密函數
def encrypt(text:bytes):
# key = '9999999999999999'.encode('utf-8')
key = 'tqsktqsktqsktqsk'.encode('utf-8')
mode = AES.MODE_CBC
iv = b'qqqqqqqqqqqqqqqq'
text = add_to_16(text)
cryptos = AES.new(key, mode, iv)
cipher_text = cryptos.encrypt(text)
# 因為AES加密后的字符串不一定是ascii字符集的,輸出保存可能存在問題,所以這里轉為16進制字符串
return b2a_hex(cipher_text)
# 解密后,去掉補足的空格用strip() 去掉
def decrypt(text):
key = 'tqsktqsktqsktqsk'.encode('utf-8')
iv = b'qqqqqqqqqqqqqqqq'
mode = AES.MODE_CBC
cryptos = AES.new(key, mode, iv)
plain_text = cryptos.decrypt(a2b_hex(text))
return plain_text
if __name__ == '__main__':
# encryption model
with open('detect_model/checkpoints/xxx_ori.pth', 'rb') as f1:
encrypted = encrypt(f1.read())
with open('detect_model/checkpoints/xxx_encryp.pth', 'wb') as f2:
f2.write(encrypted)
# decryption model
with open("./detect_model/checkpoints/xxx_decryp.pth", 'wb') as f:
content = open('detect_model/checkpoints/xxx_encryp.pth', 'rb').read()
f.write(decrypt(content))
這里用的是Crypto.Cipher模塊的AES算法。模型文件加密后會比加密前的內存大一倍左右。
問題出現了。pytorch讀取模型的函數torch.load()只能讀取文件,并且返回一個FileIO的對象,來對文件進行操作。底層都是封死的,如果我們使用加密文件的時候要先解密成文件,那還怎么保密,可是沒有辦法,只能這么做。
理論上一個可行的辦法是,把加密后的文件讀入內存,然后對讀取的內容(Bytes指針類型)進行解密,此時解密后的內容在內存中。但torch.load()只能讀取文件,所以只能使用C++自己來寫一個工具,完成內存解密的內容,加載到pytorch模型的操作,這個流程就比較復雜了,暫時沒有實現。
原文鏈接:https://blog.csdn.net/Eyesleft_being/article/details/120224243
相關推薦
- 2022-03-16 swift?cell自定義左滑手勢處理方法_Swift
- 2022-09-27 阿里云官方Redis開發規范總結_Redis
- 2023-01-13 Pytorch實現Fashion-mnist分類任務全過程_python
- 2022-04-30 詳解DataGridView控件的數據綁定_C#教程
- 2022-04-04 微信小程序:獲取用戶手機號碼的過程
- 2023-07-16 callBack: function(res){} 與 callBack: res =>{}
- 2022-04-27 Oracle?觸發器trigger使用案例_oracle
- 2022-07-03 關于python中range()的參數問題_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支