我正在尝试使用python和gnupg进行对称加密。
此代码段适用于我的windows vista机器,python gnupg模块的版本为0.3.2:
import gnupg
gpg = gnupg.GPG()
data = 'the quick brown fow jumps over the laxy dog.'
passphrase='12345'
crypt = gpg.encrypt(data, recipients=None,
symmetric='AES256',
passphrase=passphrase,
armor=False)
当我尝试使用版本1.2.5 python gnupg模块在我的linux机器上运行它时,我收到此错误:
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
File "/usr/local/lib/python2.7/dist-packages/gnupg/gnupg.py", line 961, in encrypt
result = self._encrypt(stream, recipients, **kwargs)
TypeError: _encrypt() got multiple values for keyword argument 'recipients'
我做了很多搜索,但在这方面找不到任何东西。
答案 0 :(得分:4)
这是一个古老的问题,但我在谷歌搜索中发现了这一点,并对提供的答案感到不满。我在python-gnupg的GitHub问题中找到了真正的答案:
gpg.encrypt(data, symmetric='AES256', passphrase=passphrase, armor=False, encrypt=False)
因此,请删除recipients=None
并添加encrypt=False
。然后,您的crypt.data将包含加密数据。不直观,但它确实有效。
(src:https://github.com/isislovecruft/python-gnupg/issues/110)
答案 1 :(得分:0)
仔细检查the documentation,参数不是recipient
,是recipients
(注意复数)
Docs(强调我的):
symmetric(默认为False)如果指定,则对称加密 用过的。在这种情况下,请将收件人指定为“无”。如果指定了True, 然后使用默认密码算法(CAST5)。从...开始 版本0.3.5,您还可以指定要使用的密码算法(for 例如,&#39; AES256&#39;)。检查你的gpg命令行帮助,看看是什么 支持对称密码算法。请注意默认值 (CAST5)可能不是最好的。
答案 2 :(得分:0)
这应该适用于python-gnupg 0.3.5及更高版本(根据需要进行调整):
import gnupg
gpg_home = "~/.gnupg"
gpg = gnupg.GPG(gnupghome=gpg_home)
data = raw_input("Enter full path of file to encrypt: ")
phrase = raw_input("Enter the passphrase to decrypt the file: ")
cipher = raw_input("Enter symmetric encryption algorithm to use: ")
savefile = data+".asc"
afile = open(data, "rb")
encrypted_ascii_data = gpg.encrypt_file(afile, None, passphrase=phrase, symmetric=cipher.upper(), output=savefile)
afile.close()
不确定0.3.5之前的版本。
当调用gpg.encrypt_file()时,收件人的“无”(当前版本的模块)不需要“recipients = None”。
答案 3 :(得分:0)
我认为它已经坏了(如果我错了,请纠正我)。对于Python 3.x,它似乎在gnupg 0.3.6-1
中得到修复。您可能最好使用它或尝试解决方法,例如类似于我将要描述的解决方法。
此解决方法使用Python中的命令行gpg
而不是gnupg
模块。当然,您可以使用gpg.encrypt_file
执行类似的解决方法(我不会在下一段中讨论临时存储的密码;这很可能是更好的选择。)
如果您担心任务管理器中出现的密码短语,我会将密码放在一个临时文件中并使用cat将其输入gpg
来处理。但是,可能必须担心恶意软件会从临时文件中抢夺密码,如果可以及时执行此操作。
请注意,此代码在Python 3.x中,因为这是我最常用的(在2.x中重新创建它,您必须了解临时文件在其中的工作原理,并且可能其他一些事情)。
import subprocess, tempfile, os, shutil
def gpg_encrypt(data, passphrase, alg="AES256", hash="SHA512", compress_alg="BZIP2", compress_lvl="9", iterations="1000000"):
#This is for symmetric encryption.
with tempfile.TemporaryDirectory() as directory:
filepath=os.path.join(directory, "tmp")
with open(filepath, "w") as FILE:
FILE.write(data)
iterations=str(iterations)
compress_level="--compress-level "+compress_lvl
if compress_alg.upper()=="BZIP2":
compress_level="--bzip2-compress-level "+compress_lvl
tmp_filename="tmp"
with tempfile.TemporaryDirectory() as DIR:
tmpfilepath=os.path.join(DIR, tmp_filename)
with open(tmpfilepath, "w") as FILE:
FILE.write(passphrase)
subprocess.Popen("cat "+tmpfilepath+"|gpg --batch --yes --passphrase-fd 0 --force-mdc --s2k-mode 3 --s2k-count "+iterations+" --s2k-cipher-algo "+alg+" --s2k-digest-algo "+hash+" --compress-algo='"+compress_alg+"' --compress-level "+compress_lvl+" -ac '"+filepath+"'", stdin=subprocess.PIPE, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, shell=True).communicate()[0]
result=None
with open(filepath+".asc", "r") as FILE:
result=FILE.read()
return result
def gpg_decrypt(data, passphrase):
#This is for decryption.
with tempfile.TemporaryDirectory() as directory:
filepath=os.path.join(directory, "tmp")
with open(filepath, "w") as FILE:
FILE.write(data)
decrypted=None
tmp_filename="tmp"
with tempfile.TemporaryDirectory() as DIR:
tmpfilepath=os.path.join(DIR, tmp_filename)
with open(tmpfilepath, "w") as FILE:
FILE.write(passphrase)
decrypted=subprocess.Popen("cat "+tmpfilepath+"|gpg --batch --yes --passphrase-fd 0 --output='"+filepath+".gpg"+"' '"+filepath+"'", stdin=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT, stdout=subprocess.PIPE).communicate()[0]
result=None
decrypted=not "decryption failed:" in str(decrypted)
if decrypted==True:
with open(filepath+".gpg", "r") as FILE:
result=FILE.read()
return decrypted, result #If it worked, return True. If not, return False. (And, return the decrypted data.)
test=gpg_encrypt(data="This is a test!", passphrase="enter")
print("Here is the encrypted message:\n"+test)
decrypted, data=gpg_decrypt(data=test, passphrase="enter")
if decrypted:
print("Here is the decrypted message:\n"+data)
else:
print("Incorrect passphrase to decrypt the message.")
这里是加密/解密对称加密文件的代码(仅用于衡量标准):
import subprocess, tempfile, os, shutil
def gpg_encrypt_file(filepath, passphrase, output=None, alg="AES256", hash="SHA512", compress_alg="BZIP2", compress_lvl="9", iterations="1000000"):
#This is for symmetric encryption.
filepath=filepath.replace("'", "'\\''") #This makes it so you can have apostrophes within single quotes.
iterations=str(iterations)
compress_level="--compress-level "+compress_lvl
if compress_alg.upper()=="BZIP2":
compress_level="--bzip2-compress-level "+compress_lvl
result=None
tmp_filename="tmp"
with tempfile.TemporaryDirectory() as DIR:
tmpfilepath=os.path.join(DIR, tmp_filename)
with open(tmpfilepath, "w") as FILE:
FILE.write(passphrase)
if output:
if output[0]!=os.sep and filepath[0]==os.sep:
output=os.path.join(os.path.dirname(filepath), output)
result=subprocess.Popen("cat "+tmpfilepath+"|gpg --batch --yes --passphrase-fd 0 --force-mdc --s2k-mode 3 --s2k-count "+iterations+" --s2k-cipher-algo "+alg+" --s2k-digest-algo "+hash+" --compress-algo='"+compress_alg+"' "+compress_level+" --output='"+output+"' -ac '"+filepath+"'", stdin=subprocess.PIPE, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, shell=True).communicate()[0]
else:
result=subprocess.Popen("cat "+tmpfilepath+"|gpg --batch --yes --passphrase-fd 0 --force-mdc --s2k-mode 3 --s2k-count "+iterations+" --s2k-cipher-algo "+alg+" --s2k-digest-algo "+hash+" --compress-algo='"+compress_alg+"' --compress-level "+compress_lvl+" -ac '"+filepath+"'", stdin=subprocess.PIPE, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, shell=True).communicate()[0]
return result.strip()
def gpg_decrypt_file(filepath, passphrase, output=None):
#This is for decryption.
filepath=filepath.replace("'", "'\\''")
result=None
tmp_filename="tmp"
with tempfile.TemporaryDirectory() as DIR:
tmpfilepath=os.path.join(DIR, tmp_filename)
with open(tmpfilepath, "w") as FILE:
FILE.write(passphrase)
if output:
if output[0]!=os.sep and filepath[0]==os.sep:
output=os.path.join(os.path.dirname(filepath), output)
result=subprocess.Popen("cat "+tmpfilepath+"|gpg --batch --yes --passphrase-fd 0 --output='"+output+"' '"+filepath+"'", stdin=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT, stdout=subprocess.PIPE).communicate()[0]
else:
result=subprocess.Popen("cat "+tmpfilepath+"|gpg --batch --yes --passphrase-fd 0 '"+filepath+"'", stdin=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT, stdout=subprocess.PIPE).communicate()[0]
return not "decryption failed:" in str(result) #If it worked, return True. If not, return False.
gpg_encrypt_file(filepath="test.txt", passphrase="myPassphrase", output="test.asc")
if gpg_decrypt_file(filepath="test.asc", passphrase="myPassphrase", output="output.txt"):
print("Successfully decrypted!")
else:
print("Incorrect passphrase.")