Pythonでコードを検証してデータを暗号化する方法-GnuPGとPython3

提供:Dev Guides
移動先:案内検索

著者は、 Open Internet / Free Speech Fund を選択して、 Write forDOnationsプログラムの一環として寄付を受け取りました。

序章

GnuPGパッケージは、暗号化キーを生成および保存するための完全なソリューションを提供します。 また、データと通信を暗号化して署名することもできます。

このチュートリアルでは、python-gnupgモジュールでPython3を使用する一連のスクリプトを作成します。 これらのスクリプトを使用すると、複数のファイルに署名して暗号化し、スクリプトを実行する前にスクリプトの整合性を検証できます。

前提条件

このチュートリアルを続行する前に、次の前提条件を完了してください。

  • Ubuntu 16.04 の初期サーバー設定チュートリアルに従って、Ubuntu16.04サーバーを設定します。 このチュートリアルを実行すると、root以外のsudoユーザーアカウントにアクセスできるようになります。 このチュートリアルでは、ユーザーの名前はsammyになります。
  • Python3のインストール方法とUbuntu16.04でのローカルプログラミング環境のセットアップ方法の手順1に従って、Python3とpipがインストールされていることを確認します。
  • このGnuPGチュートリアルに従って、GnuPGキーペアを作成します。

ステップ1—キーペア情報の取得

前提条件でGnuPGチュートリアルを完了すると、ホームディレクトリの下の.gnupgにキーペアが保存されます。 GnuPGは、キーのペアを識別するのに役立つユーザー名と電子メールとともにキーを保存します。 この例では、ユーザー名は sammy で、電子メールアドレスは[email protected]です。

以下のコマンドを実行して、使用可能なキーのリストを取得します。

gpg --list-keys
Output/home/sammy/.gnupg/pubring.gpg
-----------------------------
pub   2048R/4920B23F 2018-04-23
uid                  Sammy <[email protected]>
sub   2048R/50C06279 2018-04-23

出力のuid行に表示されている電子メールアドレスをメモします。 後でキーを識別するために必要になります。

ステップ2—Python-GnuPGのインストールとファイルへの署名

キーを配置したら、python-gnupgモジュールをインストールできます。このモジュールは、GnuPGのラッパーとして機能し、GnuPGとPython3の間の相互作用を可能にします。 このモジュールを使用すると、次のことを行うPythonスクリプトを作成できます。

  • ファイルの分離された署名を作成し、ファイルから署名を分離することにより、署名プロセスにセキュリティのレイヤーを追加します。
  • ファイルを暗号化します。
  • ファイルを復号化します。
  • 切り離された署名とスクリプトを確認します。

これらのファイルのスクリプトのテストに進む前に、最初にいくつかのテストファイルとともにスクリプトを作成します。

開始するには、python-gnupgモジュールを、fsパッケージと一緒にインストールします。これにより、テストファイルを開いたり、読み取ったり、書き込んだりできます。 パッケージインデックスを更新し、pipを使用してこれらのパッケージをインストールします。

sudo apt-get update
sudo pip3 install python-gnupg fs

これらのパッケージを配置したら、スクリプトとテストファイルの作成に進むことができます。

スクリプトとテストファイルを保存するには、ホームディレクトリにpython-testという名前のフォルダを作成します。

cd ~/
mkdir python-test

このディレクトリに移動します。

cd python-test/

次に、3つのテストファイルを作成しましょう。

echo "This is the first test file" > test1.txt
echo "print('This test file is a Python script')" > test2.py
echo "This is the last test file" > test3.txt

テストファイルの分離署名を作成するには、signdetach.pyというスクリプトを作成します。このスクリプトは、実行されるディレクトリ内のすべてのファイルを対象とします。 署名はタイムスタンプとして機能し、ドキュメントの信頼性を証明します。

切り離された署名は、signatures/という新しいフォルダーに保存されます。このフォルダーは、スクリプトの実行時に作成されます。

nanoまたはお気に入りのテキストエディタを使用して、signdetach.pyという名前の新しいファイルを開きます。

nano signdetach.py

まず、スクリプトに必要なすべてのモジュールをインポートしましょう。 これらには、ファイルナビゲーションを有効にするosおよびfsパッケージ、およびgnupgが含まれます。

〜/ python-test / signdetach.py

#!/usr/bin/env python3

import os
import fs
from fs import open_fs
import gnupg

次に、GnuPGが暗号化キーを見つけるディレクトリを設定しましょう。 GnuPGはデフォルトでそのキーを.gnupgに保存するので、これをユーザー名で構成しましょう。 sammyをroot以外のユーザーの名前に置き換えてください。

〜/ python-test / signdetach.py

...
gpg = gnupg.GPG(gnupghome="/home/sammy/.gnupg")

次に、home_fs変数を作成して、現在のディレクトリの場所をファイルオブジェクトとして保存しましょう。 これにより、スクリプトが実行されたディレクトリ内でスクリプトが機能するようになります。

〜/ python-test / signdetach.py

...
home_fs = open_fs(".")

これで、スクリプトは次のようになります。

〜/ python-test / signdetach.py

#!/usr/bin/env python3

import os
import fs
from fs import open_fs
import gnupg

gpg = gnupg.GPG(gnupghome="/home/sammy/.gnupg")
home_fs = open_fs(".")

この構成ブロックは、このチュートリアルを進めるときにスクリプトで使用する基本的なテンプレートです。

次に、signatures/という名前のフォルダーがあるかどうかを確認するコードを追加し、存在しない場合は作成します。

〜/ python-test / signdetach.py

...
if os.path.exists("signatures/"):
        print("Signatures directory already created")
else:
        home_fs.makedir(u"signatures")
        print("Created signatures directory")

ファイル名を格納する空の配列を作成してから、現在のディレクトリをスキャンし、すべてのファイル名をfiles_dir配列に追加します。

〜/ python-test / signdetach.py

...
files_dir = []

files = [f for f in os.listdir(".") if os.path.isfile(f)]
for f in files:
    files_dir.append(f)

スクリプトが次に行うことは、ファイルの分離された署名を生成することです。 files_dir配列をループすると、キーリングの最初の秘密鍵を使用して各ファイルの署名が作成されます。 秘密鍵にアクセスするには、設定したパスフレーズで秘密鍵のロックを解除する必要があります。 "my passphrase"を、前提条件でキーペアを生成したときに使用したパスフレーズに置き換えます。

〜/ python-test / signdetach.py

...
for x in files_dir:
    with open(x, "rb") as f:
        stream = gpg.sign_file(f,passphrase="my passphrase",detach = True, output=files_dir[files_dir.index(x)]+".sig")
        os.rename(files_dir[files_dir.index(x)]+".sig", "signatures/"+files_dir[files_dir.index(x)]+".sig")
        print(x+" ", stream.status)

完了すると、すべての署名がsignatures/フォルダーに移動されます。 完成したスクリプトは次のようになります。

[label ~/python-test/signdetach.py] 
#!/usr/bin/env python3

import os
import fs
from fs import open_fs
import gnupg

gpg = gnupg.GPG(gnupghome="/home/sammy/.gnupg")
home_fs = open_fs(".")

if os.path.exists("signatures/"):
    print("Signatures directory already created")
else:
    home_fs.makedir(u"signatures")
    print("Created signatures directory")

files_dir = []

files = [f for f in os.listdir(".") if os.path.isfile(f)]
for f in files:
    files_dir.append(f)

for x in files_dir:
    with open(x, "rb") as f:
        stream = gpg.sign_file(f,passphrase="my passphrase",detach = True, output=files_dir[files_dir.index(x)]+".sig")
        os.rename(files_dir[files_dir.index(x)]+".sig", "signatures/"+files_dir[files_dir.index(x)]+".sig")
        print(x+" ", stream.status)

これで、ファイルの暗号化に進むことができます。

ステップ3—ファイルの暗号化

フォルダ内で暗号化スクリプトを実行すると、そのフォルダ内のすべてのファイルがコピーされ、encrypted/という新しいフォルダ内で暗号化されます。 ファイルの暗号化に使用される公開鍵は、鍵ペア構成で指定した電子メールに対応するものです。

encryptfiles.pyという名前の新しいファイルを開きます。

nano encryptfiles.py

まず、必要なすべてのモジュールをインポートし、GnuPGのホームディレクトリを設定して、現在の作業ディレクトリ変数を作成します。

〜/ python-test / encodefiles.py

#!/usr/bin/env python3

import os
import fs
from fs import open_fs
import gnupg

gpg = gnupg.GPG(gnupghome="/home/sammy/.gnupg")
home_fs = open_fs(".")

次に、コードを追加して、現在のディレクトリにencrypted/というフォルダがすでにあるかどうかを確認し、存在しない場合は作成します。

〜/ python-test / encodefiles.py

...
if os.path.exists("encrypted/"):
        print("Encrypt directory exists")
else:
        home_fs.makedir(u"encrypted")
        print("Created encrypted directory")

暗号化するファイルを検索する前に、ファイル名を格納するための空の配列を作成しましょう。

〜/ python-test / encodefiles.py

...
files_dir = []

次に、フォルダーをスキャンしてファイルを探し、それらを配列に追加するループを作成します。

〜/ python-test / encodefiles.py

...
files = [f for f in os.listdir(".") if os.path.isfile(f)]
for f in files:
    files_dir.append(f)

最後に、フォルダ内のすべてのファイルを暗号化するループを作成しましょう。 完了すると、暗号化されたすべてのファイルがencrypted/フォルダーに転送されます。 この例では、[email protected]は、暗号化中に使用するキーの電子メールIDです。 これは、必ず手順1でメモした電子メールアドレスに置き換えてください。

〜/ python-test / encodefiles.py

...
for x in files_dir:
    with open(x, "rb") as f:
        status = gpg.encrypt_file(f,recipients=["[email protected]"],output= files_dir[files_dir.index(x)]+".gpg")
        print("ok: ", status.ok)
        print("status: ", status.status)
        print("stderr: ", status.stderr)
        os.rename(files_dir[files_dir.index(x)] + ".gpg", 'encrypted/' +files_dir[files_dir.index(x)] + ".gpg")

.gnupgフォルダー内に複数のキーが保存されていて、暗号化に特定の公開キーまたは複数の公開キーを使用する場合は、受信者を追加するか、置き換えることにより、recipients配列を変更する必要があります。現在のもの。

完了すると、encryptfiles.pyスクリプトファイルは次のようになります。

[label ~/python-test/encryptfiles.py] 
#!/usr/bin/env python3

import os
import fs
from fs import open_fs
import gnupg

gpg = gnupg.GPG(gnupghome="/home/sammy/.gnupg")
home_fs = open_fs(".")

if os.path.exists("encrypted/"):
    print("Encrypt directory exists")
else:
    home_fs.makedir(u"encrypted")
    print("Created encrypted directory")

files_dir = []

files = [f for f in os.listdir(".") if os.path.isfile(f)]
for f in files:
    files_dir.append(f)

for x in files_dir:
    with open(x, "rb") as f:
        status = gpg.encrypt_file(f,recipients=["[email protected]"],output= files_dir[files_dir.index(x)]+".gpg")
        print("ok: ", status.ok)
        print("status: ", status.status)
        print("stderr: ", status.stderr)
        os.rename(files_dir[files_dir.index(x)] + ".gpg", "encrypted/" +files_dir[files_dir.index(x)] + ".gpg")

次に、プロセスの2番目の部分である複数のファイルを一度に復号化して検証する方法を見てみましょう。

ステップ4—ファイルの復号化

復号化スクリプトは、encrypted/ディレクトリ内で実行されることを除いて、暗号化スクリプトとほとんど同じように機能します。 decryptfiles.pyを起動すると、最初に使用された公開鍵が識別され、次に.gnupgフォルダーで対応する秘密鍵が検索されてファイルが復号化されます。 復号化されたファイルは、decrypted/という新しいフォルダに保存されます。

nanoまたはお気に入りのエディターでdecryptfiles.pyという名前の新しいファイルを開きます。

nano decryptfiles.py

構成設定を挿入することから始めます。

〜/ python-test / decodefiles.py

#!/usr/bin/env python3

import os
import fs
from fs import open_fs
import gnupg

gpg = gnupg.GPG(gnupghome="/home/sammy/.gnupg")
home_fs = open_fs(".")

次に、スクリプトの実行中にデータを格納するための2つの空の配列を作成します。

〜/ python-test / decodefiles.py

...
files_dir = []
files_dir_clean = []

ここでの目標は、スクリプトが復号化されたファイルを独自のフォルダーに配置することです。 そうしないと、暗号化されたファイルと復号化されたファイルが混在し、特定の復号化されたファイルを見つけることが困難になります。 この問題を解決するには、現在のフォルダーをスキャンしてdecrypted/フォルダーが存在するかどうかを確認し、存在しない場合は作成するコードを追加します。

〜/ python-test / decodefiles.py

...
if os.path.exists("decrypted/"):
    print("Decrypted directory already exists")
else:
    home_fs.makedir(u"decrypted/")
    print("Created decrypted directory")

フォルダをスキャンして、すべてのファイル名をfiles_dirアレイに追加します。

〜/ python-test / decodefiles.py

...
files = [f for f in os.listdir(".") if os.path.isfile(f)]
for f in files:
    files_dir.append(f)

暗号化されたすべてのファイルには、暗号化されていることを示すためにファイル名に.gpg拡張子が追加されています。 ただし、復号化するときは、暗号化されていないため、この拡張子なしで保存する必要があります。

これを行うには、files_dir配列をループして、各ファイル名から.gpg拡張子を削除します。

〜/ python-test / decodefiles.py

...
    for x in files_dir:
            length = len(x)
            endLoc = length - 4
            clean_file = x[0:endLoc]
            files_dir_clean.append(clean_file)

新しい「クリーンアップされた」ファイル名は、file_dir_clean配列内に保存されます。

次に、ファイルをループして復号化します。 "my passphrase"をパスフレーズに置き換えて、秘密鍵のロックを解除します。

〜/ python-test / decodefiles.py

...
for x in files_dir:
    with open(x, "rb") as f:
       status = gpg.decrypt_file(f, passphrase="my passphrase",output=files_dir_clean[files_dir.index(x)])
       print("ok: ", status.ok)
       print("status: ", status.status)
       print("stderr: ", status.stderr)
       os.rename(files_dir_clean[files_dir.index(x)], "decrypted/" + files_dir_clean[files_dir.index(x)])

終了すると、スクリプトファイルは次のようになります。

[label ~/python-test/decryptfiles.py] 
#!/usr/bin/env python3

import os
import fs
from fs import open_fs
import gnupg

gpg = gnupg.GPG(gnupghome="/home/sammy/.gnupg")
home_fs = open_fs(".")

files_dir = []
files_dir_clean = []

if os.path.exists("decrypted/"):
    print("Decrypted directory already exists")
else:
    home_fs.makedir(u"decrypted/")
    print("Created decrypted directory")

files = [f for f in os.listdir(".") if os.path.isfile(f)]
for f in files:
    files_dir.append(f)

for x in files_dir:
    length = len(x)
    endLoc = length - 4
    clean_file = x[0:endLoc]
    files_dir_clean.append(clean_file)

for x in files_dir:
    with open(x, "rb") as f:
       status = gpg.decrypt_file(f, passphrase="my passphrase",output=files_dir_clean[files_dir.index(x)])
       print("ok: ", status.ok)
       print("status: ", status.status)
       print("stderr: ", status.stderr)
       os.rename(files_dir_clean[files_dir.index(x)], "decrypted/" + files_dir_clean[files_dir.index(x)])

復号化スクリプトを配置したら、複数のファイルの切り離された署名の検証に進むことができます。

ステップ5—切り離された署名の確認

複数のファイルの切り離されたデジタル署名を検証するために、verifydetach.pyスクリプトを作成してみましょう。 このスクリプトは、作業ディレクトリ内のsignatures/フォルダーを検索し、各ファイルの署名を確認します。

verifydetach.pyという名前の新しいファイルを開きます。

nano verifydetach.py

前の例のように、必要なすべてのライブラリをインポートし、作業ディレクトリとホームディレクトリを設定して、空のfiles_dir配列を作成します。

〜/ python-test / verifydetach.py

#!/usr/bin/env python3

import os
import fs
from fs import open_fs
import gnupg
    
gpg = gnupg.GPG(gnupghome="/home/sammy/.gnupg")
home_fs = open_fs(".")

files_dir = []    

次に、確認するファイルが含まれているフォルダーをスキャンしてみましょう。 ファイル名は空のfiles_dir配列に追加されます。

〜/ python-test / verifydetach.py

...
files = [f for f in os.listdir(".") if os.path.isfile(f)]
for f in files:
files_dir.append(f)

最後に、files_dir配列を移動するループを使用して、signatures/フォルダー内の各ファイルの切り離された署名を検索することにより、独自の切り離された署名を持つ各ファイルを検証しましょう。 デタッチされた署名が見つかると、それを使用してファイルを検証します。 最後の行は、各ファイルの検証のステータスを出力します。

〜/ python-test / verifydetach.py

...
for i in files_dir:
     with open("../../signatures/" + i + ".sig", "rb") as f:
         verify = gpg.verify_file(f, i)
         print(i + " ", verify.status)

終了すると、スクリプトは次のようになります。

[label ~/python-test/verifydetach.py] 
#!/usr/bin/env python3

import os
import fs
from fs import open_fs
import gnupg
    
gpg = gnupg.GPG(gnupghome="/home/sammy/.gnupg")
home_fs = open_fs(".")

files_dir = []   

files = [f for f in os.listdir(".") if os.path.isfile(f)]
for f in files:
    files_dir.append(f)

for i in files_dir:
    with open("../../signatures/" + i + ".sig", "rb") as f:
        verify = gpg.verify_file(f, i)
        print(i + " ", verify.status)

次に、サーバーで実行する前にファイルの署名を確認する方法を見ていきましょう。

ステップ6—ファイルの確認

最終的なスクリプトは、実行される前にスクリプトを検証します。 この意味では、verifydetachに似ていますが、検証済みのスクリプトを起動する追加機能があります。 スクリプトの名前を引数として取り、そのファイルの署名を検証することで機能します。 検証が成功すると、スクリプトはコンソールにメッセージを送信し、検証されたスクリプトを起動します。 検証プロセスが失敗した場合、スクリプトはエラーをコンソールに送信し、ファイルの実行を中止します。

verifyfile.pyという名前の新しいファイルを作成します。

nano verifyfile.py

まず、必要なライブラリをインポートして、作業ディレクトリを設定しましょう。

〜/ python-test / verifyfile.py

#!/usr/bin/env python3

import os
import fs
from fs import open_fs
import gnupg
    
gpg = gnupg.GPG(gnupghome="/home/sammy/.gnupg")
home_fs = open_fs(".")

スクリプトを機能させるには、検証して実行するファイルの名前を保存する必要があります。 これを行うには、script_to_runという新しい変数を作成しましょう。

〜/ python-test / verifyfile.py

...
script_to_run = str(sys.argv[1])

この変数は最初の引数を取り、新しく作成された変数内にそれを格納します。 次に、スクリプトは切り離された署名ファイルを開き、script_to_run内のファイルをその署名で検証し、検証に合格した場合に実行します。

〜/ python-test / verifyfile.py

...
with open("../../signatures/" + script_to_run + ".sig", "rb") as f:
     verify = gpg.verify_file(f, script_to_run)
     print(script_to_run + " ", verify.status)
     if verify.status == "signature valid":
          print("Signature valid, launching script...")
          exec(open(script_to_run).read())
     else:
           print("Signature invalid or missing, ")
           print("aborting script execution")

完成したスクリプトは次のようになります。

[label ~/python-test/verifyfile.py] 
#!/usr/bin/env python3

import os
import sys
import fs
from fs import open_fs
import gnupg

gpg = gnupg.GPG(gnupghome="/home/sammy/.gnupg")
home_fs = open_fs(".")

script_to_run = str(sys.argv[1])

with open("../../signatures/" + script_to_run + ".sig", "rb") as f:
    verify = gpg.verify_file(f, script_to_run)
    print(script_to_run + " ", verify.status)
    if verify.status == "signature valid":
        print("Signature valid, launching script...")
        exec(open(script_to_run).read())
    else:
        print("Signature invalid or missing, ")
        print("aborting script execution")

スクリプトの作成は完了しましたが、現時点では、現在のフォルダー内からのみ起動できます。 次のステップでは、それらの権限を変更して、グローバルにアクセスできるようにします。

ステップ7—スクリプトをシステム全体で利用できるようにする

使いやすくするために、システム上の任意のディレクトリまたはフォルダからスクリプトを実行可能にして、$PATH内に配置しましょう。 chmodコマンドを使用して、ファイルの所有者であるroot以外のユーザーに実行可能権限を付与します。

chmod +x *.py

$PATH設定を見つけるには、次のコマンドを実行します。

echo $PATH
Output-bash: /home/sammy/bin:/home/sammy/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

$PATHに保存されているファイルは、ディレクトリの権限で許可されている場合、システム内のどのフォルダからでもアクセスできます。 スクリプトは$PATH内のどこにでも配置できますが、ここでは、スクリプトをpython-test/ディレクトリから/usr/local/bin/に移動しましょう。

ファイルをコピーするときに.py拡張子を削除していることに注意してください。 作成したスクリプトの最初の行を見ると、#!usr/bin/env python3が表示されます。 この行はshebangと呼ばれ、オペレーティングシステムがコードの実行時に使用するbashインタープリターまたは環境を識別するのに役立ちます。 スクリプトを実行すると、オペレーティングシステムは、環境としてPythonを指定したことを認識し、実行のためにコードをPythonに渡します。 これは、作業したい環境を特定するのに役立つファイル拡張子が不要になったことを意味します。

sudo mv encryptfiles.py /usr/local/bin/encryptfiles
sudo mv decryptfiles.py /usr/local/bin/decryptfiles
sudo mv signdetach.py /usr/local/bin/signdetach
sudo mv verifyfile.py /usr/local/bin/verifyfile
sudo mv verifydetach.py /usr/local/bin/verifydetach

これで、スクリプト名と、スクリプトがコマンドラインから取得する可能性のある引数を実行するだけで、システム内のどこからでもスクリプトを実行できます。 次のステップでは、これらのスクリプトの使用方法の例をいくつか見ていきます。

ステップ8—スクリプトをテストする

スクリプトを$PATHに移動したので、サーバー上の任意のフォルダーからスクリプトを実行できます。

まず、pwdコマンドを使用して、python-testディレクトリ内で作業しているかどうかを確認します。

pwd

出力は次のようになります。

Output/home/sammy/python-test

チュートリアルの前半で3つのテストファイルを作成しました。 ls -lコマンドを実行して、フォルダー内のファイルを一覧表示します。

ls -l

python-testフォルダに保存されている3つのファイルが表示されます。

Output-rw-rw-r-- 1 sammy sammy 15 Apr 15 10:08 test1.txt
-rwxrwxr-x 1 sammy sammy 15 Apr 15 10:08 test2.py 
-rw-rw-r-- 1 sammy sammy 15 Apr 15 10:08 test3.txt

これら3つのファイルのスクリプトをテストします。 次のように、catコマンドを使用して、暗号化する前にファイルの内容をすばやく表示できます。

cat test1.txt
OutputThis is the first test file

すべてのファイルの分離署名を作成することから始めましょう。 これを行うには、現在のフォルダー内からsigndetachスクリプトを実行します。

signdetach
OutputCreated signatures directory
test2.py  signature created
test1.txt  signature created
test3.txt  signature created

出力で、スクリプトがsignatures/ディレクトリが存在しないことを検出し、それを作成したことに注意してください。 次に、ファイル署名を作成しました。

これは、ls -lコマンドを再度実行することで確認できます。

ls -l
Outputtotal 16
drwxrwxr-x 2 sammy sammy 4096 Apr 21 14:11 signatures
-rw-rw-r-- 1 sammy sammy 15 Apr 15 10:08 test1.txt
-rwxrwxr-x 1 sammy sammy 15 Apr 15 10:08 test2.py 
-rw-rw-r-- 1 sammy sammy 15 Apr 15 10:08 test3.txt

リストの項目の中に新しいsignaturesディレクトリがあることに注意してください。 このフォルダの内容を一覧表示して、署名の1つを詳しく見てみましょう。

すべての署名を一覧表示するには、次のように入力します。

ls -l signatures/
Outputtotal 12
-rw-rw-r-- 1 sammy sammy 473 Apr 21 14:11 test1.txt.sig
-rw-rw-r-- 1 sammy sammy 473 Apr 21 14:11 test2.py.sig
-rw-rw-r-- 1 sammy sammy 473 Apr 21 14:11 test3.txt.sig

分離された署名ファイルは、.sig拡張子で識別できます。 この場合も、catコマンドは、これらの署名の1つの内容を表示できます。 署名test1.txt.sigの内容を見てみましょう。

cat signatures/test1.txt.sig
Output-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQEcBAABAgAGBQJa20aGAAoJENVtx+Y8cX3mMhMH+gOZsLJX3aEgUPZzDlKRWYec
AyrXEGp5yIABj7eoLDKGUxftwGt+c4HZud1iEUy8AhtW/Ea6eRlMFPTso2hb9+cw
/MyffTrWGpa0AGjNvf4wbxdq7TNpAlw4nmcwKpeYqkUu2fP3c18oZ3G3R3+P781w
GWori9FK3eTyVPs9E0dVgdo7S8G1pF/ECo8Cl4Mrj80rERAitQAMbSaN/dF0wUKu
okRZPJPVjd6GwqRRkXoqwh0vm4c+p3nAhFV+v7uK2BOUIJKPFbbn58vmmn+LVaBS
MFWSb+X85KwwftIezqCV/hqsMKAuhkvfIi+YQFCDXElJMtjPBxxuvZFjQFjEHe8=
=4NB5
-----END PGP SIGNATURE-----

この出力は、test1.txtの切り離された署名です。

署名があれば、ファイルの暗号化に進むことができます。 これを行うには、encryptfilesスクリプトを実行します。

encryptfiles
OutputCreated encrypted directory
ok:  True
status:  encryption ok
stderr:  [GNUPG:] BEGIN_ENCRYPTION 2 9
[GNUPG:] END_ENCRYPTION

ok:  True
status:  encryption ok
stderr:  [GNUPG:] BEGIN_ENCRYPTION 2 9
[GNUPG:] END_ENCRYPTION

ok:  True
status:  encryption ok
stderr:  [GNUPG:] BEGIN_ENCRYPTION 2 9
[GNUPG:] END_ENCRYPTION

出力から、スクリプトがencrypted/フォルダーを作成したことに注意してください。 また、すべてのファイルが正常に暗号化されていることにも注意してください。 ls -lコマンドを再度実行し、ディレクトリ内の新しいフォルダに注目してください。

ls -l
Outputtotal 20
drwxrwxr-x 2 sammy sammy 4096 Apr 21 14:42 encrypted
drwxrwxr-x 2 sammy sammy 4096 Apr 21 14:11 signatures
-rw-rw-r-- 1 sammy sammy   15 Apr 15 10:08 test1.txt
-rw-rw-r-- 1 sammy sammy   15 Apr 15 10:08 test2.py
-rw-rw-r-- 1 sammy sammy   15 Apr 15 10:08 test3.txt

test1.txtのメッセージが暗号化された後、どのように表示されるかを見てみましょう。

cat encrypted/test1.txt.gpg
Output-----BEGIN PGP MESSAGE-----
Version: GnuPG v1

hQEMA9Vtx+Y8cX3mAQf9FijeaCOKFRUWOrwOkUw7efvr5uQbSnxxbE/Dkv0y0w8S
Y2IxQPv4xS6VrjhZQC6K2R968ZQDvd+XkStKfy6NJLsfKZM+vMIWiZmqJmKxY2OT
8MG/b9bnNCORRI8Nm9etScSYcRu4eqN7AeUdWOXAFX+mo7K00IdEQH+0Ivyc+P1d
53WBgWstt8jHY2cn1sLdoHh4m70O7v1rnkHOvrQW3AAsBbKzvdzxOa0/5IKGCOYF
yC8lEYfOihyEetsasx0aDDXqrMZVviH3KZ8vEiH2n7hDgC5imgJTx5kpC17xJZ4z
LyEiNPu7foWgVZyPzD2jGPvjW8GVIeMgB+jXsAfvEdJJAQqX6qcHbf1SPSRPJ2jU
GX5M/KhdQmBcO9Sih9IQthHDXpSbSVw/UejheVfaw4i1OX4aaOhNJlnPSUDtlcl4
AUoBjuBpQMp4RQ==
=xJST
-----END PGP MESSAGE-----

元のファイルに保存されている文は、暗号化プロセスの結果、複雑な一連の文字と数字に変換されています。

ファイルが署名および暗号化されたので、元のファイルを削除し、暗号化されたファイルから元のメッセージを復元することができます。

オリジナルを削除するには、次のように入力します。

rm *.txt *.py

ls -lコマンドを再度実行して、元のファイルがすべて削除されていることを確認します。

ls -l
Outputtotal 8
drwxrwxr-x 2 sammy sammy 4096 Apr 21 14:42 encrypted
drwxrwxr-x 2 sammy sammy 4096 Apr 21 14:11 signatures

元のファイルがなくなったら、暗号化されたファイルを復号化して検証しましょう。 encryptedフォルダーに移動し、すべてのファイルを一覧表示します。

cd encrypted/ && ls -l
Outputtotal 12
-rw-rw-r-- 1 sammy sammy 551 Apr 21 14:42 test1.txt.gpg
-rw-rw-r-- 1 sammy sammy 551 Apr 21 14:42 test2.py.gpg
-rw-rw-r-- 1 sammy sammy 551 Apr 21 14:42 test3.txt.gpg

ファイルを復号化するには、現在のフォルダー内からdecryptfilesスクリプトを実行します。

decryptfiles
OutputCreated decrypted directory
ok:  True
status:  decryption ok
stderr:  [GNUPG:] ENC_TO D56DC7E63C717DE6 1 0
[GNUPG:] USERID_HINT D56DC7E63C717DE6 Autogenerated Key <[email protected]>
[GNUPG:] NEED_PASSPHRASE D56DC7E63C717DE6 D56DC7E63C717DE6 1 0
[GNUPG:] GOOD_PASSPHRASE
gpg: encrypted with 2048-bit RSA key, ID 3C717DE6, created 2018-04-15
      "Autogenerated Key <[email protected]>"
[GNUPG:] BEGIN_DECRYPTION
[GNUPG:] DECRYPTION_INFO 2 9
[GNUPG:] PLAINTEXT 62 1524321773
[GNUPG:] PLAINTEXT_LENGTH 15
[GNUPG:] DECRYPTION_OKAY
[GNUPG:] GOODMDC
[GNUPG:] END_DECRYPTION

ok:  True
status:  decryption ok
stderr:  [GNUPG:] ENC_TO D56DC7E63C717DE6 1 0
[GNUPG:] USERID_HINT D56DC7E63C717DE6 Autogenerated Key <[email protected]>
[GNUPG:] NEED_PASSPHRASE D56DC7E63C717DE6 D56DC7E63C717DE6 1 0
[GNUPG:] GOOD_PASSPHRASE
gpg: encrypted with 2048-bit RSA key, ID 3C717DE6, created 2018-04-15
      "Autogenerated Key <[email protected]>"
[GNUPG:] BEGIN_DECRYPTION
[GNUPG:] DECRYPTION_INFO 2 9
[GNUPG:] PLAINTEXT 62 1524321773
[GNUPG:] PLAINTEXT_LENGTH 15
[GNUPG:] DECRYPTION_OKAY
[GNUPG:] GOODMDC
[GNUPG:] END_DECRYPTION

ok:  True
status:  decryption ok
stderr:  [GNUPG:] ENC_TO D56DC7E63C717DE6 1 0
[GNUPG:] USERID_HINT D56DC7E63C717DE6 Autogenerated Key <[email protected]>
[GNUPG:] NEED_PASSPHRASE D56DC7E63C717DE6 D56DC7E63C717DE6 1 0
[GNUPG:] GOOD_PASSPHRASE
gpg: encrypted with 2048-bit RSA key, ID 3C717DE6, created 2018-04-15
      "Autogenerated Key <[email protected]>"
[GNUPG:] BEGIN_DECRYPTION
[GNUPG:] DECRYPTION_INFO 2 9
[GNUPG:] PLAINTEXT 62 1524321773
[GNUPG:] PLAINTEXT_LENGTH 15
[GNUPG:] DECRYPTION_OKAY
[GNUPG:] GOODMDC
[GNUPG:] END_DECRYPTION

スクリプトは、ファイルごとにstatus: decryption okを返しました。これは、各ファイルが正常に復号化されたことを意味します。

新しいdecrypted/フォルダーに移動し、catコマンドを使用してtest1.txtの内容を表示します。

cd decrypted/ && cat test1.txt
OutputThis is the first test file

削除したtest1.txtファイルに保存されているメッセージを復元しました。

次に、verifydetachスクリプトで署名を確認して、このメッセージが実際に元のメッセージであることを確認しましょう。

署名ファイルには、署名者のIDと、署名されたドキュメントのデータを使用して計算されたハッシュ値が含まれています。 検証中、gpgは送信者の公開鍵を取得し、それをハッシュアルゴリズムと一緒に使用して、データのハッシュ値を計算します。 検証を成功させるには、計算されたハッシュ値と署名内に格納されている値が一致する必要があります。

元のファイル、署名ファイル、または送信者の公開鍵を改ざんすると、ハッシュ値が変更され、検証プロセスが失敗します。

decryptedフォルダー内からスクリプトを実行します。

verifydetach
Outputtest2.py  signature valid
test1.txt  signature valid
test3.txt  signature valid

出力から、すべてのファイルに有効な署名があることがわかります。これは、このプロセス中にドキュメントが改ざんされていないことを意味します。

署名した後でドキュメントに変更を加えたときに何が起こるかを見てみましょう。 test1.txtファイルをnanoで開きます。

nano test1.txt 

次に、次の文をファイルに追加します。

〜/python-test/encrypted/decrypted/test1.txt

This is the first test file
Let's add a sentence after signing the file

ファイルを保存して閉じます。

次に、verifydetachスクリプトを再実行して、出力がどのように変化したかを確認します。

verifydetach
Outputtest2.py  signature valid
test1.txt  signature bad
test3.txt  signature valid

test1.txtを検証するときに、GnuPGがsignature badを返したことに注意してください。 これは、署名後にファイルに変更を加えたためです。 検証プロセス中に、gpgは、署名ファイルに保存されているハッシュ値を、署名したドキュメントから計算したハッシュ値と比較することに注意してください。 ドキュメントに加えた変更により、gpgtest1.txtに対して異なるハッシュ値を計算しました。 ハッシュアルゴリズムがどのように機能するかについてのより詳細な議論はここで見つけることができます。

最後のテストでは、verifyfileを使用して、スクリプトが実行される前に検証します。 このスクリプトは、verifydetachスクリプトの拡張と見なすことができますが、次の違いがあります。スクリプトが検証プロセスに合格すると、verifyfileはスクリプトの起動に進みます。

test2.pyスクリプトは、起動時に文字列をコンソールに出力します。 これを使用して、verifyfileスクリプトがどのように機能するかを示しましょう。

test2.pyスクリプトをverifyfileで実行します。

verifyfile test2.py
Outputtest2.py  signature valid
Signature valid, launching script...
The second test file is a Python script

出力から、スクリプトがファイルの署名を検証し、その検証に基づいて適切な結果を出力してから、スクリプトを起動したことがわかります。

ファイルにコードを1行追加して、検証プロセスをテストしてみましょう。 test2.pyを開き、次のコード行を挿入します。

nano test2.py

〜/python-test/encrypted/decrypted/test2.py

print "The second test file is a Python script"
print "This line will cause the verification script to abort"

次に、verifyfileスクリプトを再実行します。

verifyfile test2.py
Outputtest2.py signature bad
Signature invalid, 
aborting script execution

スクリプトの検証に失敗したため、スクリプトの起動が中止されました。

結論

python-gnupgモジュールを使用すると、さまざまな暗号化ツールとPythonを統合できます。 データストリームの整合性を迅速に暗号化または検証する機能は、リモートデータベースサーバーへのデータのクエリや保存など、特定の状況で非常に重要です。 GnuPGキーは、バックアップの作成やSSH認証などに使用したり、VPNセットアップと組み合わせたりすることもできます。

python-gnupgモジュールの詳細については、python-gnupgプロジェクトページにアクセスしてください。 ファイルハッシュの詳細については、ダウンロードしたファイルを確認する方法のこのガイドを参照してください。