SecurityInnovation / PGPy

Pretty Good Privacy for Python
BSD 3-Clause "New" or "Revised" License
317 stars 99 forks source link

Unable to encrypt and decrypt strings using passwords: NotImplementedError #397

Open theahura opened 2 years ago

theahura commented 2 years ago

I'm running into trouble encrypting and decrypting strings with the passphrase functionality using PGPy.

def encrypt(message: str, password: str) -> pgpy.PGPMessage:
  if os.path.exists(message):
    logging.info(f'Found file at path {message}')
    with open(message, 'r') as f:
      message = f.read()

  logging.info(f'Encrypting message: {message} with password {password}')
  message = pgpy.PGPMessage.new(message, cleartext=True)
  return str(message.encrypt(password))

The above code correctly returns a PGP string, like:

-----BEGIN PGP MESSAGE-----

wy4ECQMICERvWhsooOr/hcpp3HkC4s/1R9LjznntPR7PRQOr4THq6Rcs5DGwqcBR
0ikB4zwk1TeuW2lZ6+3JFmeNvlx1dTu9+p2Ed2e+aEFBVhX79h1YAQVClA==
=mfVe
-----END PGP MESSAGE-----

I then want to unencrypt this message. I tried the following:

encrypted = encrypt('helloworld', 'password')                                         
decrypted = pgpy.PGPMessage.from_blob(encrypted).decrypt('password').message

This results in a not implemented error:

Traceback (most recent call last):
  File "encrypt.py", line 42, in <module>
    enc = pgpy.PGPMessage.from_blob(encrypted).decrypt(args.password).message
  File "/home/soot/code/soot/playground-gen/env/lib/python3.8/site-packages/pgpy/pgp.py", line 910, in message
    if self.type == 'cleartext':
  File "/home/soot/code/soot/playground-gen/env/lib/python3.8/site-packages/pgpy/pgp.py", line 941, in type
    raise NotImplementedError
NotImplementedError

Doing a bit of poking around, it looks like the _message field of the decrypted message is empty (None). What am I doing wrong?

Context: I want to send messages over the wire to and from a server from a web client using openpgp.js, so I need to convert the PGPy classes into strings or bytes somewhere at the interface.

theahura commented 2 years ago

Update: it seems like this is an issue with the cleartext parameter. In particular, the following code (taken from the examples) works:

message = PGPMessage.new("42 is quite a pleasant number")
enc_message = message.encrypt("S00per_Sekr3t")
dec_message = enc_message.decrypt("S00per_Sekr3t")
print(dec_message.message)

and this does not:

message = PGPMessage.new("42 is quite a pleasant number", cleartext=True)
enc_message = message.encrypt("S00per_Sekr3t")
dec_message = enc_message.decrypt("S00per_Sekr3t")
print(dec_message.message)