def verify_password(self, guessed_password, tryinverted=True): """Check a proposed password, to see if it's able to open and load a user's account.""" # The cleanest way to see if the password is accurate is to see if it successfully decodes the content in the account. # We can do this by attempting to decode the private key. # We can then verify it decoded properly, by re-deriving the public key, and seeing if they match. test_passkey = self.Keys['master'].get_passkey(guessed_password) byteprivatekey = base64.b64decode( self.encryptedprivkey.encode('utf-8')) # We decoded something. Check to see if we can recreate the pubkey using this. if byteprivatekey is None: return False else: test_key = Key() test_key.gpg.import_keys(byteprivatekey) reconstituted_pubkey = test_key.gpg.export_keys( test_key.gpg.list_keys()[0]['fingerprint']) test_key.pubkey = reconstituted_pubkey test_key._format_keys() if test_key.pubkey == user.pubkey: return True # Let's try one other variation before we give up. # It's possible the user has caps lock on, and so their keys are inverted. # Testing this doesn't substantially decrease security, but it does help make things easier for users who had a long day. # Based on the FB-technique, as described at http://blog.agilebits.com/2011/09/13/facebook-and-caps-lock-unintuitive-security/ if tryinverted: return self.verify_password( guessed_password=guessed_password.swapcase(), tryinverted=False)