日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

【python】python代碼加密與License控制

系統 1897 0

背景

在一些使用python的商業項目上,開發人員不想被用戶看到源代碼時,就需要對python代碼進行加密;進一步地,如果想限制用戶只能在獲得授權的機器上運行你寫的代碼時(利益相關),就需要使用License控制。只有經過加密的代碼才能進行License控制,試想一下,如果客戶能拿到你的源代碼,那么License控制就成為無稽之談。

這里提供一種代碼加密與License控制的思路。

先說python代碼加密。

代碼加密

眾所周知,python是一種開源的編程語言,在開源的語言上做加密,加密效果肯定不如編譯性語言的加密效果好,其逆向工程的難度會比編譯性語言的逆向工程簡單,按照這個思路,既然編譯性語言c/c++的逆向工程難,那么為何不先把python編譯成c/c++代碼,然后再加密呢?根據經驗這樣是可行的,且這樣加密的代碼比那些編譯成pyd文件或者打包成exe的方法就安全得多(pyd和exe的逆向工程有專門的包可以實現)。這就是這篇文章介紹的加密方法。

思路是先將py轉換為c代碼,然后編譯c為so文件。

準備工作:

linux安裝:

  • python-dev

  • gcc

    sudo apt-get install python-dev gcc

python安裝第三方庫

  • pycrypto (注意:在win10環境下安裝這個包可能會報錯,解決辦法見這里 )

  • Cython

    pip install pycrypto Cython

    加密腳本``setup.py`的代碼如下

            
              
                # coding:utf-8
              
              
                from
              
               distutils
              
                .
              
              core 
              
                import
              
               setup

              
                from
              
               Cython
              
                .
              
              Build 
              
                import
              
               cythonize

              
                import
              
               os


              
                '''
該文件的執行需要的在Terminal中輸入  python setup.py build_ext --inplace
使用Cpython 編譯python文件,關鍵函數編譯成pyd文件(相當于dll)
'''
              
              
                # 針對多文件情況設置,單文件就只寫一個就行, 文件之間用逗號隔開
              
              
key_funs 
              
                =
              
              
                [
              
              
                'test.py'
              
              
                ]
              
              

setup
              
                (
              
              
    name
              
                =
              
              
                "XX app"
              
              
                ,
              
               
    ext_modules 
              
                =
              
               cythonize
              
                (
              
              key_funs
              
                )
              
              
                ,
              
              
                )
              
              
                '''
1、將編譯后的pyd文件的命名更改成與原py文件一致
2、刪除編譯后得到的c文件和原py文件
'''
              
              
                print
              
              
                (
              
              
                "——————"
              
              
                ,
              
               os
              
                .
              
              getcwd
              
                (
              
              
                )
              
              
                ,
              
              
                "——————"
              
              
                )
              
              

files 
              
                =
              
               os
              
                .
              
              listdir
              
                (
              
              os
              
                .
              
              getcwd
              
                (
              
              
                )
              
              
                )
              
              
                print
              
              
                (
              
              files
              
                )
              
              
                for
              
               fi 
              
                in
              
               files
              
                :
              
              
                if
              
               fi
              
                .
              
              __contains__
              
                (
              
              
                ".pyd"
              
              
                )
              
              
                :
              
              
        re_name 
              
                =
              
               fi
              
                .
              
              split
              
                (
              
              
                "."
              
              
                )
              
              
                [
              
              
                0
              
              
                ]
              
              
                +
              
              
                ".pyd"
              
              
                print
              
              
                (
              
              re_name
              
                )
              
              
        os
              
                .
              
              rename
              
                (
              
              fi
              
                ,
              
               re_name
              
                )
              
              
                elif
              
               fi
              
                .
              
              __contains__
              
                (
              
              
                ".c"
              
              
                )
              
              
                or
              
               fi 
              
                in
              
               key_funs
              
                :
              
              
        os
              
                .
              
              remove
              
                (
              
              fi
              
                )
              
            
          

為了更好的說明,這里舉個簡單的例子。

另外準備兩個py文件, test.py main.py ,其中 test.py 是需要加密的代碼, main.py 是調用加密代碼的腳本,不需要加密。

test.py 的內容如下

            
              
                import
              
               datetime


              
                class
              
              
                Today
              
              
                (
              
              
                )
              
              
                :
              
              
                def
              
              
                get_time
              
              
                (
              
              self
              
                )
              
              
                :
              
              
                print
              
              
                (
              
              datetime
              
                .
              
              datetime
              
                .
              
              now
              
                (
              
              
                )
              
              
                )
              
              
                def
              
              
                say
              
              
                (
              
              self
              
                )
              
              
                :
              
              
                print
              
              
                (
              
              
                'hello world'
              
              
                )
              
            
          

main.py 的內容如下

            
              
                from
              
               test 
              
                import
              
               Today

t 
              
                =
              
               Today
              
                (
              
              
                )
              
              
t
              
                .
              
              get_time
              
                (
              
              
                )
              
              
t
              
                .
              
              say
              
                (
              
              
                )
              
            
          

加密之前,測試一下運行效果,在終端執行 python main.py ,輸出

            
              2019-08-30 11:38:38.419308
hello world

            
          

使用 setup.py test.py 進行加密

方法:將需要加密的代碼放到列表 key_funs 里面,然后在終端運行

            
              python setup.py build_ext --inplace

            
          

運行完加密腳本 setup.py 后,會將 test.py 刪掉(請備份到其他地方!),得到 test.so 文件和文件夾 build/ ,這個文件夾可以刪掉。至此代碼加密完成。

測試

再次在終端執行 python main.py ,輸出

            
              2019-08-30 11:49:17.986503
hello world

            
          

成功!

(注意,不能直接在IDE執行main.py,會出現錯誤ImportError: cannot import name ‘Today’)

License控制

知道怎么加密代碼之后,就可以用license控制你的代碼,以防被別人濫用。

通過License可以控制你的代碼,控制方式有很多種,包括限制主機、限制時間(過期則無法執行)、限制使用地點等,這里只介紹如何通過License限制主機,其他方法大同小異,做適當修改即可。

物理地址是每臺計算機獨一無二的身份號碼,我們可以利用物理地址作為限制主機的依據。

具體思路是,用戶拿到你寫的代碼后,如果用戶的計算機未經你權授則不能運行你的代碼,這時候就需要利用物理地址作為權授的載體進行授權計算機。如需要授權計算機,用戶要把需權授的機器的物理地址發給你,你使用AES加密算法把這個物理地址加密后,將得到的加密文件發給用戶(這個加密文件就相當于一把鑰匙,只有擁有這把鑰匙才能正常運行你的代碼)用戶把加密文件放到指定路徑下并執行代碼,程序讀取加密文件并解密,得到你加密的物理地址,將此物理地址與當前主機的物理地址做匹配,如果這兩個物理地址相同則程序能正常運行,不同則退出程序。這里將物理地址加密的目的是防止被用戶篡改。

這里涉及到的加密算法不做詳細介紹,需了解請移步 here

用戶計算機申請授權過程

【python】python代碼加密與License控制_第1張圖片

License控制流程圖

【python】python代碼加密與License控制_第2張圖片

具體代碼及實現例子請移步github

(別忘了點star哦)

Reference:
  • 淺談常見的七種加密算法及實現
  • 加密Python源代碼筆記

更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 长子县| 和顺县| 临漳县| 谢通门县| 井冈山市| 林口县| 麦盖提县| 梅州市| 沂水县| 西丰县| 运城市| 上思县| 许昌县| 浦东新区| 微山县| 屏东市| 麻城市| 县级市| 甘肃省| 滨州市| 雷山县| 肇庆市| 香港 | 祁阳县| 商丘市| 鹰潭市| 巴林左旗| 周口市| 来凤县| 河津市| 容城县| 河东区| 五华县| 射阳县| 灌云县| 长沙县| 平阴县| 红河县| 西安市| 克什克腾旗| 明水县|