--- a/src/eric7/Utilities/crypto/__init__.py Wed Jul 13 11:16:20 2022 +0200 +++ b/src/eric7/Utilities/crypto/__init__.py Wed Jul 13 14:55:47 2022 +0200 @@ -33,32 +33,27 @@ def pwEncode(pw): """ Module function to encode a password. - + @param pw password to encode (string) @return encoded password (string) """ pop = ( - "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" - ".,;:-_!$?*+#" + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" ".,;:-_!$?*+#" ) - rpw = ( - "".join(random.sample(pop, 32)) + - pw + - "".join(random.sample(pop, 32)) - ) + rpw = "".join(random.sample(pop, 32)) + pw + "".join(random.sample(pop, 32)) return EncodeMarker + base64.b64encode(rpw.encode("utf-8")).decode("ascii") def pwDecode(epw): """ Module function to decode a password. - + @param epw encoded password to decode (string) @return decoded password (string) """ if not epw.startswith(EncodeMarker): return epw # it was not encoded using pwEncode - + return base64.b64decode(epw[3:].encode("ascii"))[32:-32].decode("utf-8") @@ -67,14 +62,16 @@ Private module function to get the password from the user. """ global MasterPassword - + pw, ok = QInputDialog.getText( None, QCoreApplication.translate("Crypto", "Master Password"), QCoreApplication.translate("Crypto", "Enter the master password:"), - QLineEdit.EchoMode.Password) + QLineEdit.EchoMode.Password, + ) if ok: from .py3PBKDF2 import verifyPassword + masterPassword = Preferences.getUser("MasterPassword") try: if masterPassword: @@ -83,18 +80,19 @@ else: EricMessageBox.warning( None, - QCoreApplication.translate( - "Crypto", "Master Password"), + QCoreApplication.translate("Crypto", "Master Password"), QCoreApplication.translate( - "Crypto", - """The given password is incorrect.""")) + "Crypto", """The given password is incorrect.""" + ), + ) else: EricMessageBox.critical( None, QCoreApplication.translate("Crypto", "Master Password"), QCoreApplication.translate( - "Crypto", - """There is no master password registered.""")) + "Crypto", """There is no master password registered.""" + ), + ) except ValueError as why: EricMessageBox.warning( None, @@ -102,13 +100,15 @@ QCoreApplication.translate( "Crypto", """<p>The given password cannot be verified.</p>""" - """<p>Reason: {0}""".format(str(why)))) + """<p>Reason: {0}""".format(str(why)), + ), + ) def pwEncrypt(pw, masterPW=None): """ Module function to encrypt a password. - + @param pw password to encrypt (string) @param masterPW password to be used for encryption (string) @return encrypted password (string) and flag indicating @@ -119,29 +119,37 @@ __getMasterPassword() if MasterPassword is None: return "", False - + masterPW = pwDecode(MasterPassword) - + from .py3PBKDF2 import hashPasswordTuple + digestname, iterations, salt, pwHash = hashPasswordTuple(masterPW) key = pwHash[:32] from .py3AES import encryptData + try: cipher = encryptData(key, pw.encode("utf-8")) except ValueError: return "", False - return CryptoMarker + Delimiter.join([ - digestname, - str(iterations), - base64.b64encode(salt).decode("ascii"), - base64.b64encode(cipher).decode("ascii") - ]), True + return ( + CryptoMarker + + Delimiter.join( + [ + digestname, + str(iterations), + base64.b64encode(salt).decode("ascii"), + base64.b64encode(cipher).decode("ascii"), + ] + ), + True, + ) def pwDecrypt(epw, masterPW=None): """ Module function to decrypt a password. - + @param epw hashed password to decrypt (string) @param masterPW password to be used for decryption (string) @return decrypted password (string) and flag indicating @@ -149,18 +157,18 @@ """ if not epw.startswith(CryptoMarker): return epw, False # it was not encoded using pwEncrypt - + if masterPW is None: if MasterPassword is None: __getMasterPassword() if MasterPassword is None: return "", False - + masterPW = pwDecode(MasterPassword) - + from .py3AES import decryptData from .py3PBKDF2 import rehashPassword - + hashParameters, epw = epw[3:].rsplit(Delimiter, 1) try: # recreate the key used to encrypt @@ -174,7 +182,7 @@ def pwReencrypt(epw, oldPassword, newPassword): """ Module function to re-encrypt a password. - + @param epw hashed password to re-encrypt (string) @param oldPassword password used to encrypt (string) @param newPassword new password to be used (string) @@ -191,9 +199,9 @@ def pwRecode(epw, oldPassword, newPassword): """ Module function to re-encode a password. - + In case of an error the encoded password is returned unchanged. - + @param epw encoded password to re-encode (string) @param oldPassword password used to encode (string) @param newPassword new password to be used (string) @@ -201,35 +209,35 @@ """ if epw == "": return epw - + if newPassword == "": plaintext, ok = pwDecrypt(epw) - return (pwEncode(plaintext) if ok else epw) + return pwEncode(plaintext) if ok else epw else: if oldPassword == "": plaintext = pwDecode(epw) cipher, ok = pwEncrypt(plaintext, newPassword) - return (cipher if ok else epw) + return cipher if ok else epw else: npw, ok = pwReencrypt(epw, oldPassword, newPassword) - return (npw if ok else epw) + return npw if ok else epw def pwConvert(pw, encode=True): """ Module function to convert a plaintext password to the encoded form or vice versa. - + If there is an error, an empty code is returned for the encode function or the given encoded password for the decode function. - + @param pw password to encode (string) @param encode flag indicating an encode or decode function (boolean) @return encoded or decoded password (string) """ if pw == "": return pw - + if encode: # plain text -> encoded if Preferences.getUser("UseMasterPassword"): @@ -243,13 +251,13 @@ plain, ok = pwDecrypt(pw) else: plain, ok = pwDecode(pw), True - return (plain if ok else pw) + return plain if ok else pw def changeRememberedMaster(newPassword): """ Module function to change the remembered master password. - + @param newPassword new password to be used (string) """ global MasterPassword @@ -259,7 +267,7 @@ def dataEncrypt(data, password, keyLength=32, hashIterations=10000): """ Module function to encrypt a password. - + @param data data to encrypt (bytes) @param password password to be used for encryption (string) @param keyLength length of the key to be generated for encryption @@ -271,26 +279,33 @@ """ from .py3AES import encryptData from .py3PBKDF2 import hashPasswordTuple - + digestname, iterations, salt, pwHash = hashPasswordTuple( - password, iterations=hashIterations) + password, iterations=hashIterations + ) key = pwHash[:keyLength] try: cipher = encryptData(key, data) except ValueError: return b"", False - return CryptoMarker.encode("utf-8") + Delimiter.encode("utf-8").join([ - digestname.encode("utf-8"), - str(iterations).encode("utf-8"), - base64.b64encode(salt), - base64.b64encode(cipher) - ]), True + return ( + CryptoMarker.encode("utf-8") + + Delimiter.encode("utf-8").join( + [ + digestname.encode("utf-8"), + str(iterations).encode("utf-8"), + base64.b64encode(salt), + base64.b64encode(cipher), + ] + ), + True, + ) def dataDecrypt(edata, password, keyLength=32): """ Module function to decrypt a password. - + @param edata hashed data to decrypt (string) @param password password to be used for decryption (string) @param keyLength length of the key to be generated for decryption @@ -300,10 +315,10 @@ """ if not edata.startswith(CryptoMarker.encode("utf-8")): return edata, False # it was not encoded using dataEncrypt - + from .py3AES import decryptData from .py3PBKDF2 import rehashPassword - + hashParametersBytes, edata = edata[3:].rsplit(Delimiter.encode("utf-8"), 1) hashParameters = hashParametersBytes.decode() try: