Pythonコードを保護するにはどうすればよいですか?
-
06-07-2019 - |
質問
私は、私の雇用主の顧客に配布されるPythonのソフトウェアを開発しています。私の雇用主は、時間制限のあるライセンスファイルでソフトウェアの使用を制限したいと考えています。
.pyファイルまたは.pycファイルを配布する場合、ライセンスファイルをチェックするコードを簡単に(逆コンパイルして)削除できます。
もう1つの側面は、私の雇用主がコードが顧客に読まれることを望んでいないことです。コードが盗まれるか、少なくとも「新しいアイデア」を恐れます。
この問題を処理する良い方法はありますか?できれば市販のソリューションを使用してください。
ソフトウェアはLinuxシステム上で実行されます(したがって、py2exeがそのトリックを行うとは思わない)。
解決
Pythonは、バイトコードでコンパイルされたインタープリター言語であるため、ロックダウンするのが非常に困難です。 py2exe のようなexeパッケージャーを使用している場合でも、実行可能ファイルのレイアウトはよく知られており、Pythonバイトコードよく理解されています。
通常、このようなケースでは、トレードオフが必要です。コードを保護することは本当に重要ですか?そこに本当の秘密(銀行振込の対称暗号化の鍵など)がありますか、それとも単に妄想的ですか?最高の製品を最も早く開発できる言語を選択し、斬新なアイデアがどれほど価値があるかを現実的に考えてください。
ライセンスチェックを本当に安全に実施する必要があると判断した場合、ライセンスチェックコードをリバースエンジニアリングするのが非常に難しく(不可能ではない!)できるように、小さなC拡張として記述し、 Pythonのコード。
他のヒント
"この問題を処理する良い方法はありますか?"いいえ。リバースエンジニアリングから保護できるものはありません。 DVDマシンのファームウェアでさえリバースエンジニアリングされ、 AACS暗号化キーが公開されています。そして、それはDMCAがそれを犯罪にしているにもかかわらずです。
顧客がコードを読むのを止める技術的な方法はないため、通常の商用方法を適用する必要があります。
-
ライセンス。契約。規約と条件。これは、人々がコードを読み取れる場合でも機能します。一部のPythonベースのコンポーネントでは、これらのコンポーネントを使用してソフトウェアを販売する前に料金を支払う必要がある場合があります。また、一部のオープンソースライセンスでは、そのコンポーネントのソースまたは起源を隠すことを禁止しています。
-
重要な値を提供します。拒否するのが難しい価格であなたの物が非常に良いなら、何かをリバースエンジニアリングするために時間とお金を無駄にする動機はありません。リバースエンジニアリングは高価です。製品をわずかに安くします。
-
リバースエンジニアリングを悪いアイデアにするアップグレードと拡張機能を提供します。次のリリースでリバースエンジニアリングが中断されても、意味がありません。これは馬鹿げた極端な話にもなりますが、リバースエンジニアリングよりも次のリリースの価値を高める新しい機能を提供する必要があります。
-
非常に魅力的なレートでカスタマイズを提供して、拡張機能をビルドしてサポートすることを望んでいます。
-
期限切れのライセンスキーを使用します。これは残酷であり、あなたに悪い評判を与えますが、それは確かにあなたのソフトウェアの動作を停止させます。
-
Webサービスとして提供します。 SaaSには顧客へのダウンロードは含まれません。
Pythonは必要なツールではありません
正しいことを行うには適切なツールを使用する必要があり、Pythonは難読化するようには設計されていません。それは逆です。それは言語の哲学であるため、すべてがオープンであるか、Pythonで簡単に公開または変更できます。
見えないものが必要な場合は、別のツールを探してください。これは悪いことではありません。使用方法が異なる複数の異なるツールが存在することが重要です。
難読化は本当に難しい
コンパイルされたプログラムでもリバースエンジニアリングできるため、コードを完全に保護できるとは思わないでください。難読化されたPHPを分析したり、フラッシュ暗号化キーを破ったりすることができます。新しいバージョンのWindowsは毎回クラックされます。
法的要件を持つことは良い方法です
誰かがあなたのコードを悪用するのを防ぐことはできませんが、誰かがそうするかどうかは簡単に発見できます。したがって、それは単なる法的な問題です。
コード保護が過大評価されている
最近では、ビジネスモデルは製品ではなくサービスを販売する傾向があります。サービスをコピーしたり、海賊行為をしたり、盗んだりすることはできません。たぶん、フローを使用することを検討する時間です...
Pythonをコンパイルしてバイナリを配布します!
賢明なアイデア:
Cython 、を使用しますNuitka 、 Shed Skin 、またはPythonをCコードにコンパイルするための類似物。次に、アプリをPythonバイナリとして配布します。代わりにライブラリ(pyd)。
そのように、Python(バイト)コードは残されておらず、通常のコードから誰もが期待できる合理的な量の不明瞭化を行ったと思います。 (バイトコードは難読化されておらず、比較的簡単に適切なソースに逆コンパイルできるため、.NETまたはJavaはこの場合より安全性が低くなります。)
CythonはCPythonとの互換性を高めているため、動作するはずです。 (私たちの製品では実際にこれを検討しています。私たちはすでにいくつかのサードパーティのライブラリをpyd / dllとしてビルドしているため、独自のPythonコードをバイナリとして出荷することはあまり大きなステップではありません。)
このブログ投稿(私ではありません)。 (thx @hithwen)
クレイジーなアイデア:
CythonでモジュールごとにCファイルを個別に保存し、それらをすべて連結して、重いインライン化でビルドすることができます。そうすれば、Pythonモジュールは非常にモノリシックであり、一般的なツールでチップ化するのは困難です。
クレイジーを超えて:
Pythonランタイムとすべてのライブラリ(dll)に静的にリンク(および最適化)できる場合、単一の実行可能ファイルをビルドできる場合があります。そうすれば、Pythonや使用するフレームワークライブラリとの間の呼び出しをインターセプトすることは確実に困難になります。ただし、LGPLコードを使用している場合、これは実行できません。
あなたの雇用主は、彼が「盗む」ことができることを知っていますか?他の人があなたのコードから得るアイデアをバックアップしますか?彼らがあなたの作品を読むことができれば、あなたも彼らの作品を読むことができます。状況からどのように利益を得ることができるかを考えれば、どれだけ失う可能性があるかを恐れるよりも、投資のより良いリターンをもたらすでしょう。
[編集]ニックのコメントへの回答:
何も得られず、何も失われません。顧客は自分が望むものを持っています(そして、彼が自分で変更を行ったので、代金を支払いました)。彼は変更をリリースしていないので、それは他のすべての人に起きなかったかのようです。
顧客がソフトウェアを販売している場合、著作権表示を変更する必要があります(これは違法であるため、訴訟を起こして勝訴します->単純なケース)。
著作権表示を変更しない場合、第2レベルの顧客は、ソフトウェアがオリジナルのものであることに気付き、何が起こっているのか疑問に思います。彼らはあなたに連絡する可能性があるので、あなたはあなたの仕事の再販について学ぶでしょう。
ここでも2つのケースがあります。元の顧客が販売したコピーはわずかでした。それは彼らがとにかく多くのお金をmakeけなかったことを意味します。または、大量に販売しました。それは、あなたが彼らが何をするかを学び、それについて何かをする良い機会を意味します。
しかし、最終的には、ほとんどの企業は法律を順守しようとします(評判が損なわれると、ビジネスを行うのがはるかに難しくなります)。したがって、彼らはあなたの仕事を盗むのではなく、あなたと協力して改善します。そのため、ソースを(単純な再販から保護するライセンスを使用して)含めると、変更が次のバージョンにあることを確認し、それを維持する必要がないため、彼らが行った変更を単にプッシュバックする可能性があります。それは双方にとって好都合です:公式リリースにそれを含めたくない場合でも、あなたは変更を受け取り、彼らが本当に、必死にそれを必要とするなら、彼らは自分で変更を加えることができます。
pyminifier をご覧になりましたか? Pythonコードの縮小、難読化、圧縮を行います。サンプルコードは、カジュアルなリバースエンジニアリングにはかなり厄介に見えます。
$ pyminifier --nonlatin --replacement-length=50 /tmp/tumult.py
#!/usr/bin/env python3
ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲמּ=ImportError
ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ燱=print
ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ巡=False
ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ澨=object
try:
import demiurgic
except ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲמּ:
ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ燱("Warning: You're not demiurgic. Actually, I think that's normal.")
try:
import mystificate
except ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲמּ:
ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ燱("Warning: Dark voodoo may be unreliable.")
ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲﺬ=ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ巡
class ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ𐦚(ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ澨):
def __init__(self,*args,**kwargs):
pass
def ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ클(self,dactyl):
ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ퐐=demiurgic.palpitation(dactyl)
ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ𠛲=mystificate.dark_voodoo(ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ퐐)
return ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ𠛲
def ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ𐠯(self,whatever):
ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ燱(whatever)
if __name__=="__main__":
ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ燱("Forming...")
ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲﺃ=ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ𐦚("epicaricacy","perseverate")
ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲﺃ.ﺭ异𞸐𐤔ﭞﰣﺁں𝕌𨿩𞸇뻛𐬑𥰫嬭ﱌ𢽁𐡆𧪮Ꝫﴹ뙫𢤴퉊ﳦﲣפּܟﺶ𐐤ﶨࠔ𐰷𢡶𧐎𐭈𞸏𢢘𦘼ﶻ𩏃𦽨𞺎𠛘𐠲䉊ﰸﭳᣲ𐠯("Codswallop")
# Created by pyminifier (https://github.com/liftoff/pyminifier)
難読化に依存しないでください。あなたが正しく結論付けたように、それは非常に限られた保護を提供します。 更新:リバースエンジニアリングされた論文へのリンク Dropboxの難読化されたPythonコード。アプローチ-オペコードの再マッピングは良い障壁ですが、明らかにそれは打ち負かすことができます。
代わりに、多くのポスターが言及しているように、それを作ります:
- リバースエンジニアリングに時間をかける価値はありません(ソフトウェアは非常に優れているので、支払うのは理にかなっています)
- 契約に署名させ、可能であればライセンス監査を実施します。
別の方法として、キックIDE Python IDE WingIDEが行うように:コードを提供します。そうです、コードを渡して、アップグレードとサポートのために人々を呼び戻してください。
.pycファイルの配送には問題があります-作成されたpythonバージョン以外のpythonバージョンとの互換性がないため、製品が実行されるシステムで実行されているpythonバージョンを知る必要があります。それは非常に制限的な要因です。
状況によっては、組織のホストするWebサービスにソフトウェアの(すべて、または少なくとも重要な部分)を移動できる場合があります。
このようにして、ライセンスチェックは安全なサーバールームで実行できます。
完璧な解決策はありませんが、次のことが可能です:
- いくつかの重要なスタートアップコードをネイティブライブラリに移動します。
- ネイティブライブラリでライセンスチェックを強制します。
ネイティブコードへの呼び出しを削除する場合、プログラムはとにかく起動しません。削除されない場合、ライセンスが適用されます。
これはクロスプラットフォームまたは純粋なPythonソリューションではありませんが、動作します。
コードを保護するための信頼できる唯一の方法は、制御するサーバーでコードを実行し、そのサーバーとインターフェイスするクライアントをクライアントに提供することです。
Pythonコードを保護するもう1つの方法があると思います。難読化メソッドの一部。 Mount and Bladeなどのゲームがあり、独自のpythonインタープリター(オープンソースであると信じる元のインタープリター)を変更して再コンパイルし、OPコードテーブルのOPコードを標準のpython OPとは異なるものに変更したものがあると思いますコード。
したがって、Pythonソースは変更されていませんが、*。pycファイルのファイル拡張子は異なり、opコードは公開されているpython.exeインタープリターと一致しません。ゲームデータファイルをチェックした場合、すべてのデータはPythonソース形式でした。
このようにして、未熟なハッカーを混乱させるために、あらゆる種類の厄介なトリックを行うことができます。経験の浅いハッカーの集団を止めるのは簡単です。プロのハッカーがあなたを倒すことはないでしょう。しかし、ほとんどの企業は、プロのハッカーを私が想像するスタッフに長くとどめていません(おそらくハッキングされるため)。しかし、未熟なハッカーはいたるところにいます(好奇心IT盛なITスタッフとして読まれます)。
たとえば、変更されたインタープリターで、ソース内の特定のコメントまたはドキュメント文字列をチェックすることができます。このようなコード行には特別なOPコードを使用できます。例:
OP 234は、ソース行"#Copyright I written this ''のためのものです。 または、その行を" if False:"と同等のopコードにコンパイルします。 "#Copyright"不足している。基本的に、コードのブロック全体を無効にすることは、あいまいな理由と思われます。
修正されたインタープリターを再コンパイルすることが可能なユースケースの1つは、アプリを作成しなかった場合、アプリは大きいが、金融の専用サーバー管理者である場合など、それを保護するための支払いが必要な場合ですアプリ。
ソースまたはオペコードを眼球用に開いたままにしておくのは少し矛盾していますが、ネットワークトラフィックにはSSLを使用します。 SSLも100%安全ではありません。しかし、それは最も目がそれを読むのを止めるのに用いられます。ちょっとした予防策が賢明です。
また、Pythonのソースとオペコードがあまりにも目に見えると十分に考えている人がいる場合、少なくともシンプルな保護ツールを誰かが最終的に開発する可能性があります。そのため、「Pythonアプリを保護する方法」を求める人が増えています。その開発を促進するだけです。
クライアントが誰であるかに応じて、賢明なライセンス契約と組み合わせた単純な保護メカニズムは、複雑なライセンス/暗号化/難読化システムよりもはるかに効果的です。
最良の解決策は、サービスをホストする、またはサポートを提供するなどして、コードをサービスとして販売することです。ただし、必ずしも実用的ではありません。
コードを .pyc
ファイルとして配送すると、数個の#
によって保護が妨げられるのを防ぐことができますが、海賊版保護の効果はほとんどありません技術)、そして一日の終わりには、会社との適切なライセンス契約が達成することは何も達成すべきではありません。
コードをできるだけ使いやすくすることに集中してください。顧客を満足させることは、理論上の著作権侵害を防ぐよりもはるかに多くのお金を稼ぐことができます。
Cython を使用します。モジュールを高性能のCファイルにコンパイルし、ネイティブバイナリライブラリにコンパイルできます。 .pycバイトコードと比較して、これは基本的に元に戻せません!
CythonをPythonプロジェクト用にセットアップする方法に関する詳細な記事を書きました。チェックしてください:
コードを盗みにくくするもう1つの試みは、jythonを使用してから java obfuscator を使用することです。
これはjythoncがpythonコードをjavaに変換し、javaがバイトコードにコンパイルされるので、かなりうまくいくはずです。したがって、クラスを難読化すると、実際のコードを回復することは言うまでもなく、逆コンパイル後に何が起こっているのかを理解することは本当に難しくなります。
jythonの唯一の問題は、cで記述されたpythonモジュールを使用できないことです。
重要なファイルをハッシュおよび署名し、公開キーメソッドでチェックすることにより、標準の暗号化スキームでコードに署名するのはどうですか?
この方法で、各顧客の公開鍵を含むライセンスファイルを発行できます。
さらに、 this のようなPython難読化ツールを使用できます(ちょうどgoogled)。
getdropbox.comのスタッフがLinuxを含むクライアントソフトウェアに対してどのように実行するかを見てください。クラッキングするのは非常に難しく、保護メカニズムを通過するにはかなり創造的な分解が必要です。
どの回答にも pyconcrete が表示されないことに驚きました。質問よりも新しいからでしょうか?
それはまさにあなたが必要とするものである可能性があります。
コードを難読化する代わりに、ロード時に暗号化および復号化します。
pypiページから:
Pythonスクリプトのワークフローを保護する
- your_script.py
pyconcreteをインポート
- pyconcreteはインポートモジュールをフックします
- スクリプトが
MODULE
をインポートするとき、 pyconcrete importフックは、最初にMODULE.pye
を見つけようとし、次に_pyconcrete.pyd
を介してMODULE.pye
を復号化し、復号化されたデータを実行します( .pyc content)- 暗号化&
_pyconcrete.pyd
の秘密鍵レコードを解読します (DLLやSOなど)秘密鍵はバイナリコードで非表示になります。 HEXビューで直接表示
Pythonでできることは、わかりにくくすることです。
- すべてのドキュメント文字列を削除
- .pycコンパイル済みファイルのみを配布します。
- フリーズ
- クラス/モジュール内の定数を隠して、help(config)がすべてを表示しないようにします
その一部を暗号化し、その場で復号化してeval()に渡すことで、さらに不明瞭な部分を追加できる場合があります。しかし、あなたが何をするにしても、誰かがそれを破ることができます。
これのいずれも、決心した攻撃者がバイトコードを分解したり、ヘルプやディレクトリなどを使用してapiを掘ったりするのを阻止します。
時間制限のあるライセンスを持ち、ローカルにインストールされたプログラムでそれをチェックするというアイデアは機能しません。完全に難読化されていても、ライセンスチェックは削除できます。ただし、リモートシステムでライセンスを確認し、閉じたリモートシステムでプログラムの大部分を実行すると、IPを保護できます。
競合他社がソースコードを独自に使用したり、同じコードのインスピレーションバージョンを記述したりするのを防ぐための1つの保護方法は、プログラムロジックに署名を追加することです(コードが盗まれたことを証明できる秘密) Pythonソースコードを難読化するので、読みやすく利用するのが困難です。
適切な難読化により、基本的にコードに保護が追加されます。コードを実行可能ファイルにコンパイルする(およびバイナリを除去する)場合と同じです。難読化された複雑なコードがどのように機能するかを理解することは、実際に独自の実装を作成するよりもさらに難しい場合があります。
これは、プログラムのハッキングの防止には役立ちません。難読化コードを使用してもライセンスが解読され、プログラムの動作が若干異なるように変更される場合があります(コードをバイナリにコンパイルしてもネイティブプログラムの保護に役立たないのと同じ方法で)。
シンボルの難読化に加えて、コードのリファクタリングを解除することをお勧めします。これにより、すべてがさらに混乱します。実際にはそれらの異なる場所が同じことをしても、グラフのポイントは多くの異なる場所を指します。
難読化されたコード内の論理署名(たとえば、プログラムロジックで使用されるが署名としても使用される値のテーブルを作成できます)。これは、コードがあなたから発信されたことを判断するために使用できます。難読化されたコードモジュールを自分の製品の一部として使用することを決定した場合(それを再難読化して異なるように見せても)見せることができる場合、そのコードは秘密の署名で盗まれます。
私は自分のプロジェクトのソフトウェア保護全般を検討しましたが、一般的な哲学は完全な保護は不可能だということです。達成できると期待できる唯一のことは、別のライセンスを購入するよりもバイパスする方がコストがかかるレベルに保護を追加することです。
それでは、Pythonの難読化についてgoogleをチェックしているだけで、何も表示していません。 .Netソリューションでは、難読化がWindowsプラットフォームでの問題に対する最初のアプローチになりますが、LinuxでMonoで動作するソリューションがあるかどうかはわかりません。
次は、コンパイル済みの言語でコードを記述することです。または、本当に最後までやりたい場合は、アセンブラーで行います。削除された実行可能ファイルは、インタプリタ言語よりも逆コンパイルがはるかに困難です。
それはすべてトレードオフに帰着します。一方では、Pythonでのソフトウェア開発が容易であり、秘密を隠すことも非常に困難です。一方、アセンブラーで記述されたソフトウェアは、作成がはるかに困難ですが、秘密を隠すのがはるかに簡単です。
上司は、その連続体に沿って、要件をサポートするポイントを選択する必要があります。そして、彼はあなたが彼が望むものを構築できるようにあなたにツールと時間を与えなければなりません。しかし、私の賭けは、彼が潜在的な金銭的損失に対して実際の開発コストに反対するということです。
メモリにロードして実行するCランチャーの暗号化されたリソースにpy2exeバイトコードを含めることができます。いくつかのアイデアこちらおよびこちら。
自己修正プログラムについても考えていますエンジニアリングは高価です。
デバッガー防止のチュートリアル、逆アセンブラーの失敗、偽のデバッガーブレークポイントを使用し、チェックサムでコードを保護します。 [「暗号化されたコード」」を検索します他のリンクについては「メモリ内」を実行します。
しかし、他の人がすでに言ったように、あなたのコードにそれだけの価値がある場合、リバースエンジニアは最終的に成功します。
ソフトウェアライセンスに焦点を当てる場合は、こちらに書いた別のStack Overflowの回答をご覧になることをお勧めします。ライセンスキー検証システムの構築方法のインスピレーションを取得します。
GitHub には、ライセンスの確認に役立つオープンソースライブラリがあります。ビット。
pip install license
でインストールし、次のコードを追加できます:
pubKey = "<RSAKeyValue><Modulus>sGbvxwdlDbqFXOMlVUnAF5ew0t0WpPW7rFpI5jHQOFkht/326dvh7t74RYeMpjy357NljouhpTLA3a6idnn4j6c3jmPWBkjZndGsPL4Bqm+fwE48nKpGPjkj4q/yzT4tHXBTyvaBjA8bVoCTnu+LiC4XEaLZRThGzIn5KQXKCigg6tQRy0GXE13XYFVz/x1mjFbT9/7dS8p85n8BuwlY5JvuBIQkKhuCNFfrUxBWyu87CFnXWjIupCD2VO/GbxaCvzrRjLZjAngLCMtZbYBALksqGPgTUN7ZM24XbPWyLtKPaXF2i4XRR9u6eTj5BfnLbKAU5PIVfjIS+vNYYogteQ==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>"
res = Key.activate(token="WyIyNTU1IiwiRjdZZTB4RmtuTVcrQlNqcSszbmFMMHB3aWFJTlBsWW1Mbm9raVFyRyJd",\
rsa_pub_key=pubKey,\
product_id=3349, key="ICVLD-VVSZR-ZTICT-YKGXL", machine_code=Helpers.GetMachineCode())
if res[0] == None not Helpers.IsOnRightMachine(res[0]):
print("An error occured: {0}".format(res[1]))
else:
print("Success")
RSA公開キーなどの設定方法について詳しくは、こちらをご覧ください。
同じ方法を使用して、c / c ++のバイナリファイルを保護します。つまり、実行可能ファイルまたはライブラリバイナリファイル内の各関数本体を難読化し、命令「ジャンプ」を挿入します。各関数エントリの開始時に、難読化されたコードを復元する特別な機能にジャンプします。バイトコードはPythonスクリプトのバイナリコードなので、
- 最初にPythonスクリプトをコンパイルしてオブジェクトをコーディングする
- 次に、各コードオブジェクトを繰り返し、各コードオブジェクトのco_codeを次のように難読化します
0 JUMP_ABSOLUTE n = 3 + len(bytecode) 3 ... ... Here it's obfuscated bytecode ... n LOAD_GLOBAL ? (__pyarmor__) n+3 CALL_FUNCTION 0 n+6 POP_TOP n+7 JUMP_ABSOLUTE 0
- 難読化されたコードオブジェクトを.pycまたは.pyoファイルとして保存
これらの難読化されたファイル(.pycまたは.pyo)は、これらのコードオブジェクトが最初に呼び出されたときに、通常のpythonインタープリターによって使用できます
-
最初のopはJUMP_ABSOLUTEで、オフセットnにジャンプします
-
オフセットnで、命令はPyCFunctionを呼び出すことです。この関数は、オフセット3とnの間の難読化されたバイトコードを復元し、元のバイトコードをオフセット0に配置します。難読化されたコードは、次のコードで取得できます
char *obfucated_bytecode; Py_ssize_t len; PyFrameObject* frame = PyEval_GetFrame(); PyCodeObject *f_code = frame->f_code; PyObject *co_code = f_code->co_code; PyBytes_AsStringAndSize(co_code, &obfucated_bytecode, &len)
-
この関数が戻った後、最後の命令は オフセット0。実際にバイトコードが実行されるようになりました。
この方法でpythonスクリプトを難読化するためのツール Pyarmor があります。