

python（pygame）で事前に暗号化したファイルを復号して処理に使用したいと思っています。  
復号してファイルに書き出すことで、暗号化する前の状態に戻すことはできたのですが  
このままだと書き出したファイルをユーザーが好きに扱えるのではないかと苦慮しています

こういう場合の対策や方法をご教授いただきたいと思います。

以下サンプルソースです

[code]

    import os
    import pygame
    from Crypto.PublicKey import RSA
    from Crypto.Cipher import AES, PKCS1_OAEP
    
    TARGET_PATH = os.path.join(os.path.dirname(__file__), "../data")
    
    PEM = "===himitsukagi==="
    
    def decrypto_file(path):
        # 復号
        file_in = open(path, "rb")
        private_key = RSA.import_key(PEM)
        enc_session_key, nonce, tag, ciphertext = [file_in.read(x) for x in (private_key.size_in_bytes(), 16, 16, -1)]
        # セッションキーをRSA秘密鍵で復号する
        cipher_rsa = PKCS1_OAEP.new(private_key)
        session_key = cipher_rsa.decrypt(enc_session_key)
        # データをAESセッションキーで復号する
        cipher_aes = AES.new(session_key, AES.MODE_EAX, nonce)
        data = cipher_aes.decrypt_and_verify(ciphertext, tag)
    
        return data
    
    
    if __name__ == "__main__":
        # 初期化
        pygame.init()
        screen = pygame.display.set_mode((1280,720))
        
    
        path = TARGET_PATH + "/crypto_file.sample"
        data = decrypto_file(path)
    
        # 本当はここで音楽ファイルを読み込みたい
        # pygame.mixer.music.load(data)
    
        # 打開策として一度ファイルに書き出して読み取っている
        file_out = open("decrypto_file.ogg", "wb")
        file_out.write(data)
        file_out.close()
        pygame.mixer.music.load("decrypto_file.ogg")
    
        pygame.mixer.music.play()
        is_end = False
        while(1):
            # 背景
            screen.fill((100,100,100))
    
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    is_end = True
    
            if is_end : break
    
    
[/code]

2022/02/04追記：  
解析が容易であるという指摘を受けましたので、以下の場合でも保護が不可能かご教授いただければ幸いです

  1. 本番ではPEMをAPI通信で専用の「APIKEY」「パラメータ」「URL」がないと取れないようにします
  2. pythonのコードは有償のpyarmorを使い、極力難読化させたうえでexe化して使用します

ここで質問ですが、この手順を踏んでもプログラムで使用している変数及びメディアデータは、メモリからあっさり抽出されたりするのでしょうか？  
また、抽出する方法は市販のツールだったり、OSの標準ツールだったりしますでしょうか？  
その抽出方法がわかれば更に追加手順として以下のことも視野に入れたいと思っています

  3. その方法を使えないようプログラムで制御します（できるなら…）

以上、お手数ですが何卒よろしくお願いします


CC BY-SA 4.0
2022-01-30T12:00:35.270
86019
2022-02-05T00:59:45.167
2022-02-03T15:26:20.573
50657
50657
question
python pygame pycrypto
pythonで暗号化ファイルを復号した後読み取りを行う方法


復号したdataをバイナリストリームで`pygame.mixer.music.load`に渡せば、ファイルを作成せずに再生できると思います。

[code]

        # 本当はここで音楽ファイルを読み込みたい
        # pygame.mixer.music.load(data)
        # 打開策として一度ファイルに書き出して読み取っている
        # file_out = open("decrypto_file.ogg", "wb")
        # file_out.write(data)
        # file_out.close()
        # pygame.mixer.music.load("decrypto_file.ogg")
    
        import io
        bytesIO = io.BytesIO(bytes(data))
        pygame.mixer.music.load(bytesIO)
    
        pygame.mixer.music.play()
    
[/code]

[music - Pygameドキュメント
日本語訳](http://westplain.sakuraweb.com/translate/pygame/Music.cgi)によると`pygame.mixer.music.load`は「音楽ファイル名や音楽オブジェクトを読み込み、」とあります。  
試しに音楽ファイルから読み込んだdataをバイナリストリームにして`pygame.mixer.music.load`に渡したところ音楽が再生できました。


CC BY-SA 4.0
2022-02-02T13:45:32.693
86104
2022-02-02T13:45:32.693
35558
86019
answer


> 書き出したファイルをユーザーが好きに扱えるのではないかと苦慮しています

想定されるのは

  * 「ユーザー」が復号データを抜き出すことができる
  * 「ユーザー」がファイルを触ることでプログラムの動作が意図せぬ動作をする

という問題だと思います。

前者に関して言うと、ファイルに書き出そうがオンメモリで処理しようが大して差はありません。「ユーザー」の環境でデータを再生する以上、「ユーザー」はデータに容易にアクセスできます。さらに、このコードベースであれば暗号化キーにも容易にアクセスできるので、そもそも暗号化する意味がありません。

逆に、「ユーザー」からデータを保護しようとするとこれはいわゆる「プロテクト」の話となり相当難易度の高い課題となります。

後者について言えば、ファイルのロック等で回避できますが無駄な処理なのでオンメモリで処理する意味はあります。が、前述の通りそもそも暗号化に意味がないので、そもそも元データをそのまま読ませた方がましです。

* * *

求められているのは「プロテクト」の話のようですが上にに書いたとおりこれは難易度が高い課題です。コストをかけてでもやらないといけないう話なら専門の企業に相談された方が良いです。または専用機向けに開発するという手もあります。

鍵をオンラインで送るのは何の意味もありません。その鍵は簡単に読むことができます。ではその鍵を暗号化したらどうでしょう。鍵を復号する鍵はどこに保管しておくのでしょうか。ローカルにあるなら最初からその鍵を使えばいいだけでオンラインで送るのは単に無駄という話にしかなりません。

まず暗号について基礎を学ばれることをおすすめします。暗号が何に対して保護を提供するのか(何に対しては保護を提供しないのか)を理解されたほうがいいでしょう。


CC BY-SA 4.0
2022-02-03T12:20:25.333
86123
2022-02-05T00:59:45.167
2022-02-05T00:59:45.167
5793
5793
86019
answer