2011-04-15 60 views
4

我有验证签名与Python gnupg模块的问题。 有了这个模块我可以加密和签名文件:如何用Python gnupg模块验证gnupg签名?

gpg: encrypted with 2048-bit ELG-E key, ID 518CD1AD, created 2011-04-14 
      "client" 
gpg: Signature made 04/14/11 13:36:14 using DSA key ID C7C006DD 
gpg: Good signature from "server" 

它可以被Python解密gnupg模块太,输出文件:

gpg.encrypt_file(stream, encrypt_for, sign=sign_by, passphrase=key_passwd, output=file_out) 

这样加密的文件可以通过命令行gpg,输出被解密已解密内容, 但我无法验证签名。该解密并验证码:

def decrypt_file(file_in, file_out, key_passwd): 
    gpg = gnupg.GPG() 
    f = open(file_in, "rb") 
    data = f.read() 
    f.close() 
    gpg.decrypt(data, passphrase=key_passwd, output=file_out) 
    verified = gpg.verify(data) 
    if not verified: 
     raise ValueError("Signature could not be verified!") 

例外,我得到了:

decrypting file... 
Exception in thread Thread-12: 
Traceback (most recent call last): 
    File "c:\Python26\lib\threading.py", line 534, in __bootstrap_inner 
     self.run() 
    File "c:\Python26\lib\threading.py", line 486, in run 
     self.__target(*self.__args, **self.__kwargs) 
    File "c:\Python26\lib\site-packages\gnupg.py", line 202, in _read_response 
     result.handle_status(keyword, value) 
    File "c:\Python26\lib\site-packages\gnupg.py", line 731, in handle_status 
     raise ValueError("Unknown status message: %r" % key) 
ValueError: Unknown status message: u'UNEXPECTED' 

Traceback (most recent call last): 
    File "ht_gnupg.py", line 32, in <module> 
     test() 
    File "ht_gnupg.py", line 27, in test 
     decrypt_file('test_p.enc', 'test_p.txt', 'client') 
    File "ht_gnupg.py", line 18, in decrypt_file 
     raise ValueError("Signature could not be verified!") 
ValueError: Signature could not be verified! 

我用gnupg-0.2.7python-gnupg-0.2.7.win32.exe与ActiveStatus的Python 2.6。

我也试过gpg.verify_file()但我得到了同样的错误。文件是ASCII装甲,看起来像:

-----BEGIN PGP MESSAGE----- 
Version: GnuPG v1.4.9 (MingW32) 

hQIOA0EAndRRjNGtEAf/YxMQaFMnBwT3Per6ypoMYaO1AKQikRgJJMJ90a/EoZ44 
... 
=G6Ai 
-----END PGP MESSAGE----- 

如何验证签名,如命令行gpg

回答

4

有关示例脚本,请参阅this gist,该脚本向您展示如何在解密时验证签名。

代码(截至2011-04-05)如下:

from cStringIO import StringIO 
import gnupg 
import logging 
import os 
import shutil 

def generate_key(gpg, first_name, last_name, domain, passphrase=None): 
    "Generate a key" 
    params = { 
     'Key-Type': 'DSA', 
     'Key-Length': 1024, 
     'Subkey-Type': 'ELG-E', 
     'Subkey-Length': 2048, 
     'Name-Comment': 'A test user', 
     'Expire-Date': 0, 
    } 
    params['Name-Real'] = '%s %s' % (first_name, last_name) 
    params['Name-Email'] = ("%s.%[email protected]%s" % (first_name, last_name, domain)).lower() 
    if passphrase is None: 
     passphrase = ("%s%s" % (first_name[0], last_name)).lower() 
    params['Passphrase'] = passphrase 
    cmd = gpg.gen_key_input(**params) 
    return gpg.gen_key(cmd) 

def init_logging(): 
    logging.basicConfig(level=logging.DEBUG, filename="gpg.log", 
         filemode="w", format="%(asctime)s %(levelname)-5s %(name)-10s %(threadName)-10s %(message)s") 

def print_info(decrypted): 
    print('User name: %s' % decrypted.username) 
    print('Key id: %s' % decrypted.key_id) 
    print('Signature id: %s' % decrypted.signature_id) 
    #print('Signature timestamp: %s' % decrypted.sig_timestamp) 
    print('Fingerprint: %s' % decrypted.fingerprint) 

def main(): 
    init_logging() 
    if os.path.exists('keys'): 
     shutil.rmtree('keys') 
    gpg = gnupg.GPG(gnupghome='keys') 
    key = generate_key(gpg, "Andrew", "Able", "alpha.com", 
          passphrase="andy") 
    andrew = key.fingerprint 
    key = generate_key(gpg, "Barbara", "Brown", "beta.com") 
    barbara = key.fingerprint 
    #First - without signing 
    data = 'Top secret' 
    encrypted = gpg.encrypt_file(StringIO(data), barbara, 
           #sign=andrew, passphrase='andy', 
           output='encrypted.txt') 
    assert encrypted.status == 'encryption ok' 
    # Data is in encrypted.txt. Read it in and verify/decrypt it. 
    data = open('encrypted.txt', 'r').read() 
    decrypted = gpg.decrypt(data, passphrase='bbrown', output='decrypted.txt') 
    print_info(decrypted) 
    #Now with signing 
    data = 'Top secret' 
    encrypted = gpg.encrypt_file(StringIO(data), barbara, 
           sign=andrew, passphrase='andy', 
           output='encrypted.txt') 
    assert encrypted.status == 'encryption ok' 
    # Data is in encrypted.txt. Read it in and verify/decrypt it. 
    data = open('encrypted.txt', 'r').read() 
    decrypted = gpg.decrypt(data, passphrase='bbrown', output='decrypted.txt') 
    print_info(decrypted) 

if __name__ == '__main__': 
    main() 
+0

谢谢它工作得很好。我认为在'gnupg'主文档中显示它是值得的,''decrypt()'返回的对象信息很少。 – 2011-04-18 04:48:58

+0

完成后,请参阅http://packages.python.org/python-gnupg/#using-signing-and-encryption-together – 2011-04-19 13:23:26