52 return epw # it was not encoded using pwEncode |
52 return epw # it was not encoded using pwEncode |
53 |
53 |
54 return base64.b64decode(epw[3:].encode("ascii"))[32:-32].decode("utf-8") |
54 return base64.b64decode(epw[3:].encode("ascii"))[32:-32].decode("utf-8") |
55 |
55 |
56 |
56 |
57 def __getMasterPassword(): |
57 def __getMainPassword(): |
58 """ |
58 """ |
59 Private module function to get the password from the user. |
59 Private module function to get the password from the user. |
60 """ |
60 """ |
61 from .py3PBKDF2 import verifyPassword |
61 from .py3PBKDF2 import verifyPassword |
62 |
62 |
63 global MasterPassword |
63 global MainPassword |
64 |
64 |
65 pw, ok = QInputDialog.getText( |
65 pw, ok = QInputDialog.getText( |
66 None, |
66 None, |
67 QCoreApplication.translate("Crypto", "Master Password"), |
67 QCoreApplication.translate("Crypto", "Main Password"), |
68 QCoreApplication.translate("Crypto", "Enter the master password:"), |
68 QCoreApplication.translate("Crypto", "Enter the main password:"), |
69 QLineEdit.EchoMode.Password, |
69 QLineEdit.EchoMode.Password, |
70 ) |
70 ) |
71 if ok: |
71 if ok: |
72 masterPassword = Preferences.getUser("MasterPassword") |
72 mainPassword = Preferences.getUser("MainPassword") |
73 try: |
73 try: |
74 if masterPassword: |
74 if mainPassword: |
75 if verifyPassword(pw, masterPassword): |
75 if verifyPassword(pw, mainPassword): |
76 MasterPassword = pwEncode(pw) |
76 MainPassword = pwEncode(pw) |
77 else: |
77 else: |
78 EricMessageBox.warning( |
78 EricMessageBox.warning( |
79 None, |
79 None, |
80 QCoreApplication.translate("Crypto", "Master Password"), |
80 QCoreApplication.translate("Crypto", "Main Password"), |
81 QCoreApplication.translate( |
81 QCoreApplication.translate( |
82 "Crypto", """The given password is incorrect.""" |
82 "Crypto", """The given password is incorrect.""" |
83 ), |
83 ), |
84 ) |
84 ) |
85 else: |
85 else: |
86 EricMessageBox.critical( |
86 EricMessageBox.critical( |
87 None, |
87 None, |
88 QCoreApplication.translate("Crypto", "Master Password"), |
88 QCoreApplication.translate("Crypto", "Main Password"), |
89 QCoreApplication.translate( |
89 QCoreApplication.translate( |
90 "Crypto", """There is no master password registered.""" |
90 "Crypto", """There is no main password registered.""" |
91 ), |
91 ), |
92 ) |
92 ) |
93 except ValueError as why: |
93 except ValueError as why: |
94 EricMessageBox.warning( |
94 EricMessageBox.warning( |
95 None, |
95 None, |
96 QCoreApplication.translate("Crypto", "Master Password"), |
96 QCoreApplication.translate("Crypto", "Main Password"), |
97 QCoreApplication.translate( |
97 QCoreApplication.translate( |
98 "Crypto", |
98 "Crypto", |
99 """<p>The given password cannot be verified.</p>""" |
99 """<p>The given password cannot be verified.</p>""" |
100 """<p>Reason: {0}""".format(str(why)), |
100 """<p>Reason: {0}""".format(str(why)), |
101 ), |
101 ), |
102 ) |
102 ) |
103 |
103 |
104 |
104 |
105 def pwEncrypt(pw, masterPW=None): |
105 def pwEncrypt(pw, mainPW=None): |
106 """ |
106 """ |
107 Module function to encrypt a password. |
107 Module function to encrypt a password. |
108 |
108 |
109 @param pw password to encrypt (string) |
109 @param pw password to encrypt (string) |
110 @param masterPW password to be used for encryption (string) |
110 @param mainPW password to be used for encryption (string) |
111 @return encrypted password (string) and flag indicating |
111 @return encrypted password (string) and flag indicating |
112 success (boolean) |
112 success (boolean) |
113 """ |
113 """ |
114 from .py3AES import encryptData |
114 from .py3AES import encryptData |
115 from .py3PBKDF2 import hashPasswordTuple |
115 from .py3PBKDF2 import hashPasswordTuple |
116 |
116 |
117 if masterPW is None: |
117 if mainPW is None: |
118 if MasterPassword is None: |
118 if MainPassword is None: |
119 __getMasterPassword() |
119 __getMainPassword() |
120 if MasterPassword is None: |
120 if MainPassword is None: |
121 return "", False |
121 return "", False |
122 |
122 |
123 masterPW = pwDecode(MasterPassword) |
123 mainPW = pwDecode(MainPassword) |
124 |
124 |
125 digestname, iterations, salt, pwHash = hashPasswordTuple(masterPW) |
125 digestname, iterations, salt, pwHash = hashPasswordTuple(mainPW) |
126 key = pwHash[:32] |
126 key = pwHash[:32] |
127 try: |
127 try: |
128 cipher = encryptData(key, pw.encode("utf-8")) |
128 cipher = encryptData(key, pw.encode("utf-8")) |
129 except ValueError: |
129 except ValueError: |
130 return "", False |
130 return "", False |
140 ), |
140 ), |
141 True, |
141 True, |
142 ) |
142 ) |
143 |
143 |
144 |
144 |
145 def pwDecrypt(epw, masterPW=None): |
145 def pwDecrypt(epw, mainPW=None): |
146 """ |
146 """ |
147 Module function to decrypt a password. |
147 Module function to decrypt a password. |
148 |
148 |
149 @param epw hashed password to decrypt (string) |
149 @param epw hashed password to decrypt (string) |
150 @param masterPW password to be used for decryption (string) |
150 @param mainPW password to be used for decryption (string) |
151 @return decrypted password (string) and flag indicating |
151 @return decrypted password (string) and flag indicating |
152 success (boolean) |
152 success (boolean) |
153 """ |
153 """ |
154 from .py3AES import decryptData |
154 from .py3AES import decryptData |
155 from .py3PBKDF2 import rehashPassword |
155 from .py3PBKDF2 import rehashPassword |
156 |
156 |
157 if not epw.startswith(CryptoMarker): |
157 if not epw.startswith(CryptoMarker): |
158 return epw, False # it was not encoded using pwEncrypt |
158 return epw, False # it was not encoded using pwEncrypt |
159 |
159 |
160 if masterPW is None: |
160 if mainPW is None: |
161 if MasterPassword is None: |
161 if MainPassword is None: |
162 __getMasterPassword() |
162 __getMainPassword() |
163 if MasterPassword is None: |
163 if MainPassword is None: |
164 return "", False |
164 return "", False |
165 |
165 |
166 masterPW = pwDecode(MasterPassword) |
166 mainPW = pwDecode(MainPassword) |
167 |
167 |
168 hashParameters, epw = epw[3:].rsplit(Delimiter, 1) |
168 hashParameters, epw = epw[3:].rsplit(Delimiter, 1) |
169 try: |
169 try: |
170 # recreate the key used to encrypt |
170 # recreate the key used to encrypt |
171 key = rehashPassword(masterPW, hashParameters)[:32] |
171 key = rehashPassword(mainPW, hashParameters)[:32] |
172 plaintext = decryptData(key, base64.b64decode(epw.encode("ascii"))) |
172 plaintext = decryptData(key, base64.b64decode(epw.encode("ascii"))) |
173 except ValueError: |
173 except ValueError: |
174 return "", False |
174 return "", False |
175 return plaintext.decode("utf-8"), True |
175 return plaintext.decode("utf-8"), True |
176 |
176 |
248 else: |
248 else: |
249 plain, ok = pwDecode(pw), True |
249 plain, ok = pwDecode(pw), True |
250 return plain if ok else pw |
250 return plain if ok else pw |
251 |
251 |
252 |
252 |
253 def changeRememberedMaster(newPassword): |
253 def changeRememberedMain(newPassword): |
254 """ |
254 """ |
255 Module function to change the remembered master password. |
255 Module function to change the remembered main password. |
256 |
256 |
257 @param newPassword new password to be used (string) |
257 @param newPassword new password to be used (string) |
258 """ |
258 """ |
259 global MasterPassword |
259 global MainPassword |
260 MasterPassword = pwEncode(newPassword) if newPassword else None |
260 MainPassword = pwEncode(newPassword) if newPassword else None |
261 |
261 |
262 |
262 |
263 def dataEncrypt(data, password, keyLength=32, hashIterations=10000): |
263 def dataEncrypt(data, password, keyLength=32, hashIterations=10000): |
264 """ |
264 """ |
265 Module function to encrypt a password. |
265 Module function to encrypt a password. |