如何使用Python-GnuPG和Python3 實現數據的解密和加密


介紹

GnuPG包提供用於生成和存儲加密密鑰的完整解決方案。它還允許您加密和簽名數據和通信。

在本教程中,您將創建一系列使用Python 3和python-gnupg模塊的腳本。這些腳本允許您對多個文件進行簽名和加密,並在運行腳本之前驗證腳本的完整性。

准備

在繼續本教程之前,請完成以下條件:

  • Ubuntu 16.04服務器,擁有sudo權限的非root用戶。在本教程中,我們的用戶將被命名為sammy
  • 確保您已安裝Python 3和pip,安裝教程詳見鏈接。
  • 創建GnuPG密鑰對。

第1步 - 檢索密鑰對信息

 brew install gnupg

sudo pip3 install python-gnupg

 

接收到公鑰后,在命令行輸入“gpg --import ytyzx2014gpgpublickey.txt”導入公鑰。

 

完成准備中的GnuPG教程后,您將在主目錄下的.gnupg存儲密鑰對。GnuPG使用用戶名和電子郵件存儲密鑰,以幫助識別密鑰對。在此示例中,我們的用戶名是sammy,我們的電子郵件地址是sammy@example.com

運行以下命令以獲取可用密鑰的列表:

$  gpg --list-keys
/home/sammy/.gnupg/pubring.gpg
-----------------------------
pub   2048R/4920B23F 2018-04-23
uid                  Sammy <sammy@example.com>
sub   2048R/50C06279 2018-04-23

記下uid輸出行中顯示的電子郵件地址。稍后您將需要它來識別您的密鑰。

第2步 - 安裝Python-GnuPG和簽名文件

使用您的密鑰,您可以安裝python-gnupg模塊,該模塊充當GnuPG的包裝器,以實現GnuPG和Python 3之間的交互。使用此模塊,您將能夠創建執行以下操作的Python腳本:

  • 為文件創建分離的簽名,通過從文件中分離簽名,為簽名過程添加一層安全性。
  • 加密文件。
  • 解密文件。
  • 驗證分離的簽名和腳本。

在繼續測試這些文件上的腳本之前,您將首先創建腳本以及一些測試文件。

首先,讓我們安裝python-gnupg模塊以及fs包,這將允許您打開,讀取和編寫測試文件。更新包索引,並使用pip命令安裝這些包:

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

有了這些軟件包,我們就可以繼續創建腳本和測試文件。

要存儲腳本和測試文件,請在主目錄中創建一個名為python-test的文件夾:

$ cd ~/
$ mkdir python-test

移至此目錄:

$ cd python-test/

接下來,讓我們創建三個測試文件:

$ 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

讓我們首先導入腳本所需的所有模塊。這些包括啟用文件導航的osfs包,以及gnupg

~/python-test/signdetach.py

#!/usr/bin/env python3

import os
import fs
from fs import open_fs
import gnupg

現在讓我們設置GnuPG的加密密鑰的目錄。GnuPG默認存儲其密鑰在.gnupg上,所以讓我們用我們的用戶名配置它。請務必使用非root用戶的名稱替換sammy

~/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/文件夾。您完成的腳本將如下所示:

~/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/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(".")

接下來,讓我們添加代碼來檢查當前目錄是否已經有一個名為encrypted/的文件夾,如果它不存在則創建它:

~/python-test/encryptfiles.py

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

在搜索要加密的文件之前,讓我們創建一個空數組來存儲文件名:

~/python-test/encryptfiles.py

...
files_dir = []

接下來,創建一個循環來掃描文件夾中的文件並將它們附加到數組:

~/python-test/encryptfiles.py

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

最后,讓我們創建一個循環來加密文件夾中的所有文件。完成后,所有加密文件都將傳輸到該encrypted/文件夾。在此示例中sammy\@example.com是加密期間要使用的密鑰的電子郵件ID。請務必將其替換為您在步驟1中記下的電子郵件地址:

~/python-test/encryptfiles.py

...
for x in files_dir:
    with open(x, "rb") as f:
        status = gpg.encrypt_file(f,recipients=["sammy@example.com"],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腳本文件將如下所示:

~/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=["sammy@example.com"],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")

現在讓我們看一下該過程的第二部分:一次解密和驗證多個文件。

第4步 - 解密文件

解密腳本與加密腳本的工作原理大致相同,只是它要在encrypted/目錄中執行。啟動時,decryptfiles.py將首先識別使用的公鑰,然后在.gnupg文件夾中搜索相應的私鑰以解密文件。解密的文件將存儲在一個名為decrypted/的新文件夾中。

打開一個名為decryptfiles.py的新文件:

$ nano decryptfiles.py

首先插入配置設置:

~/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(".")

接下來,創建兩個空數組以在腳本執行期間存儲數據:

~/python-test/decryptfiles.py

...
files_dir = []
files_dir_clean = []

這里的目標是讓腳本將解密后的文件放入自己的文件夾中;否則,加密和解密的文件將混合,難以找到特定的解密文件。要解決此問題,您可以添加將掃描當前文件夾以查看decrypted/文件夾是否存在的代碼,如果不存在,則創建該文件夾:

~/python-test/decryptfiles.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/decryptfiles.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/decryptfiles.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"為您的密碼以解鎖私鑰:

...
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)])

完成后,您的腳本文件將如下所示:

~/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)

完成后,您的腳本將如下所示:

~/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")

完成的腳本將如下所示:

~/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
-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

輸出應該是:

/home/sammy/python-test

您在本教程前面創建了三個測試文件。運行該ls -l命令以列出文件夾中的文件:

$ ls -l

您應該看到文件python-test夾中存儲了三個文件:

-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

我們將測試這三個文件的腳本。您可以使用cat命令在加密前快速顯示文件的內容,如下所示:

$ cat test1.txt
This is the first test file

讓我們首先為所有文件創建分離簽名。為此,請從當前文件夾中執行signdetach腳本:

$ signdetach
Created signatures directory
test2.py  signature created
test1.txt  signature created
test3.txt  signature created

請注意,在輸出中,腳本檢測到signatures/目錄不存在,所以之后創建了它。然后它也創建了文件簽名。

我們可以通過ls -l再次運行命令來確認:

$ ls -l
total 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目錄。讓我們列出這個文件夾的內容,並仔細查看其中一個簽名。

要列出所有簽名,請鍵入:

$ ls -l signatures/
total 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命令可以顯示這些簽名的內容。我們來看看test1.txt.sig簽名的內容:

$ cat signatures/test1.txt.sig
-----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
Created 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
total 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
-----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
total 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
total 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 \<sammy\@example.com\>

[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 \<sammy\@example.com\>"

[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 \<sammy\@example.com\>

[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 \<sammy\@example.com\>"

[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 \<sammy\@example.com\>

[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 \<sammy\@example.com\>"

[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
This is the first test file

我們已經恢復了test1.txt中我們刪除的文件中存儲的消息。

接下來,讓我們通過使用verifydetach腳本驗證其簽名來確認此消息確實是原始消息。

簽名文件包含簽名者的身份以及使用簽名文檔中的數據計算的哈希值。在驗證期間,gpg將獲取發送方的公鑰並將其與散列算法一起使用以計算數據的哈希值。計算的散列值和簽名中存儲的值需要匹配才能使驗證成功。

任何對原始文件,簽名文件或發件人公鑰的篡改都將導致哈希值發生變化,驗證過程將失敗。

decrypted文件夾中運行腳本:

$ verifydetach
test2.py  signature valid
test1.txt  signature valid
test3.txt  signature valid

您可以從輸出中看到所有文件都具有有效簽名,這意味着在此過程中文檔未被篡改。

現在讓我們看一下在您簽署文檔后對文檔進行更改時會發生什么。使用nano打開test1.txt文件:

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
test2.py  signature valid
test1.txt  signature bad
test3.txt  signature valid

請注意,GnuPG在驗證test1.txt時返回signature bad。這是因為我們在簽名后對文件進行了更改。請記住,在驗證過程中,gpg將簽名文件中存儲的哈希值與您從簽名文檔中計算的哈希值進行比較。我們對test1.txt文檔所做的更改導致gpg計算出不同的哈希值。

對於我們的上一次測試,讓我們在腳本執行之前使用verifyfile來驗證腳本。此腳本可以看作是腳本verifydetach的擴展,但有以下區別:如果腳本通過驗證過程,verifyfile將繼續啟動它。

test2.py腳本在啟動時會將字符串輸出到控制台。讓我們用它來演示verifyfile腳本的工作原理。

使用verifyfile運行test2.py腳本:

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

從輸出中可以看到腳本驗證了文件的簽名,根據該驗證打印了適當的結果,然后啟動了腳本。

讓我們通過在文件中添加額外的代碼行來測試驗證過程。打開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
test2.py signature bad
Signature invalid, 
aborting script execution

腳本驗證失敗,導致腳本啟動中止。

結論

該python-gnupg模塊允許在各種加密工具和Python之間進行集成。在某些情況下,例如查詢或將數據存儲到遠程數據庫服務器,快速加密或驗證數據流完整性的能力至關重要。GnuPG密鑰還可用於加密Apple Mail的郵件


參考文獻:《How To Verify Code and Encrypt Data with Python-GnuPG and Python 3》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM