mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-30 18:05:55 +01:00 
			
		
		
		
	password change (reencryption)
This commit is contained in:
		
							
								
								
									
										74
									
								
								change-password.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								change-password.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | |||||||
|  | #!/usr/bin/python | ||||||
|  |  | ||||||
|  | import src.config_provider | ||||||
|  | import src.sql | ||||||
|  | import base64 | ||||||
|  | import getpass | ||||||
|  | from Crypto.Cipher import AES | ||||||
|  | from Crypto.Util import Counter | ||||||
|  | import binascii | ||||||
|  |  | ||||||
|  | import src.my_scrypt | ||||||
|  |  | ||||||
|  | currentPassword = getpass.getpass(prompt="Enter current password: ") | ||||||
|  |  | ||||||
|  | currentPasswordHash = binascii.hexlify(src.my_scrypt.getVerificationHash(currentPassword)) | ||||||
|  |  | ||||||
|  | config = src.config_provider.getConfig() | ||||||
|  |  | ||||||
|  | if currentPasswordHash != config['Login']['passwordHash']: | ||||||
|  |     print("Given password doesn't match hash") | ||||||
|  |     exit(-1) | ||||||
|  |  | ||||||
|  | currentPasswordEncryptionKey = src.my_scrypt.getEncryptionHash(currentPassword) | ||||||
|  |  | ||||||
|  | newPassword1 = getpass.getpass(prompt="Enter new password: ") | ||||||
|  | newPassword2 = getpass.getpass(prompt="Repeat the same password: ") | ||||||
|  |  | ||||||
|  | if newPassword1 != newPassword2: | ||||||
|  |     print('Entered passwords are not identical!') | ||||||
|  |     exit(-1) | ||||||
|  |  | ||||||
|  | newPasswordVerificationKey = binascii.hexlify(src.my_scrypt.getVerificationHash(newPassword1)) | ||||||
|  | newPasswordEncryptionKey = src.my_scrypt.getEncryptionHash(newPassword1) | ||||||
|  |  | ||||||
|  | src.sql.connect(config['Document']['documentPath']) | ||||||
|  |  | ||||||
|  | encryptedNotes = src.sql.getResults("select note_id, note_title, note_text from notes where encryption = 1") | ||||||
|  |  | ||||||
|  | def decrypt(encryptedBase64): | ||||||
|  |     encryptedBytes = base64.b64decode(encryptedBase64) | ||||||
|  |  | ||||||
|  |     aes = getAes(currentPasswordEncryptionKey) | ||||||
|  |     return aes.decrypt(encryptedBytes) | ||||||
|  |  | ||||||
|  | def encrypt(plainText): | ||||||
|  |     aes = getAes(newPasswordEncryptionKey) | ||||||
|  |     encryptedBytes = aes.encrypt(plainText) | ||||||
|  |  | ||||||
|  |     return base64.b64encode(encryptedBytes) | ||||||
|  |  | ||||||
|  | def getAes(key): | ||||||
|  |     return AES.new(key, AES.MODE_CTR, counter=Counter.new(128, initial_value=5)) | ||||||
|  |  | ||||||
|  | for note in encryptedNotes: | ||||||
|  |     decryptedTitle = decrypt(note['note_title']) | ||||||
|  |     decryptedText = decrypt(note['note_text']) | ||||||
|  |  | ||||||
|  |     reEncryptedTitle = encrypt(decryptedTitle) | ||||||
|  |     reEncryptedText = encrypt(decryptedText) | ||||||
|  |  | ||||||
|  |     print (reEncryptedTitle) | ||||||
|  |     print (reEncryptedText) | ||||||
|  |  | ||||||
|  |     src.sql.execute("update notes set note_title = ?, note_text = ? where note_id = ?", | ||||||
|  |                     [reEncryptedTitle, reEncryptedText, note['note_id']]) | ||||||
|  |  | ||||||
|  |     print("Note " + note['note_id'] + " reencrypted with new password") | ||||||
|  |  | ||||||
|  | print("New password hash is: " + newPasswordVerificationKey) | ||||||
|  | print("Set this value to passwordHash value in config.ini") | ||||||
|  |  | ||||||
|  | src.sql.commit() | ||||||
|  |  | ||||||
|  | print("Changes committed. All encrypted notes were re-encrypted successfully with new password key.") | ||||||
| @@ -17,7 +17,7 @@ certKeyPath=cert.key | |||||||
| # Enter below credentials with with which you want to authenticate to Notecase web app | # Enter below credentials with with which you want to authenticate to Notecase web app | ||||||
| username=your_username | username=your_username | ||||||
| # This is bcrypt password hash. You can use generate-password.py (in this directory) to hash your password | # This is bcrypt password hash. You can use generate-password.py (in this directory) to hash your password | ||||||
| password-hash=$2b$12$FHT8keXp3BGTfzAV/VnrkuLpkwN8Vpj5iIh4RwCbHTNWYSBI9hGAK | passwordHash=$2b$12$FHT8keXp3BGTfzAV/VnrkuLpkwN8Vpj5iIh4RwCbHTNWYSBI9hGAK | ||||||
|  |  | ||||||
| [Sync] | [Sync] | ||||||
| sync-server-url=https://localhost:57201 | sync-server-url=https://localhost:57201 | ||||||
|   | |||||||
| @@ -1,28 +1,15 @@ | |||||||
| #!/usr/bin/python | #!/usr/bin/python | ||||||
|  |  | ||||||
| import getpass | import getpass | ||||||
|  | import src.my_scrypt | ||||||
| import scrypt  # pip install scrypt |  | ||||||
| import binascii |  | ||||||
|  |  | ||||||
| password1 = getpass.getpass() | password1 = getpass.getpass() | ||||||
|  | password2 = getpass.getpass(prompt='Repeat the same password:') | ||||||
| print('Repeat the same password:') |  | ||||||
|  |  | ||||||
| password2 = getpass.getpass() |  | ||||||
|  |  | ||||||
| if password1 == password2: | if password1 == password2: | ||||||
|     # salt is constant |     hash = src.my_scrypt.getVerificationHash(password1) | ||||||
|     salt = "dc73b57736511340f132e4b5521d178afa6311c45e0c25e6a9339038507852a6" |  | ||||||
|  |  | ||||||
|     hashed = scrypt.hash(password=password1, |  | ||||||
|                            salt=salt, |  | ||||||
|                            N=16384, |  | ||||||
|                            r=8, |  | ||||||
|                            p=1, |  | ||||||
|                            buflen=32) |  | ||||||
|  |  | ||||||
|     print('Generated password hash:') |     print('Generated password hash:') | ||||||
|     print(binascii.hexlify(hashed)) |     print(hash) | ||||||
| else: | else: | ||||||
|     print('Entered passwords are not identical!') |     print('Entered passwords are not identical!') | ||||||
							
								
								
									
										0
									
								
								src/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								src/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -2,7 +2,6 @@ import os | |||||||
|  |  | ||||||
| import binascii | import binascii | ||||||
| import scrypt | import scrypt | ||||||
| import configparser |  | ||||||
| from flask import Flask, request, send_from_directory | from flask import Flask, request, send_from_directory | ||||||
| from flask import render_template, redirect | from flask import render_template, redirect | ||||||
| from flask_cors import CORS | from flask_cors import CORS | ||||||
| @@ -13,9 +12,9 @@ from sql import connect | |||||||
| from tree_api import tree_api | from tree_api import tree_api | ||||||
| from notes_move_api import notes_move_api | from notes_move_api import notes_move_api | ||||||
| from password_api import password_api | from password_api import password_api | ||||||
|  | import config_provider | ||||||
|  |  | ||||||
| config = configparser.ConfigParser() | config = config_provider.getConfig() | ||||||
| config.read('config.ini') |  | ||||||
|  |  | ||||||
| app = Flask(__name__) | app = Flask(__name__) | ||||||
| app.secret_key = config['Security']['flaskSecretKey'] | app.secret_key = config['Security']['flaskSecretKey'] | ||||||
| @@ -54,7 +53,7 @@ documentPath = config['Document']['documentPath'] | |||||||
|  |  | ||||||
| connect(documentPath) | connect(documentPath) | ||||||
|  |  | ||||||
| hashedPassword = config['Login']['password-hash'].encode('utf-8') | hashedPassword = config['Login']['passwordHash'].encode('utf-8') | ||||||
|  |  | ||||||
|  |  | ||||||
| def verify_password(hex_hashed_password, guessed_password): | def verify_password(hex_hashed_password, guessed_password): | ||||||
|   | |||||||
							
								
								
									
										7
									
								
								src/config_provider.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/config_provider.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | import configparser | ||||||
|  |  | ||||||
|  | def getConfig(): | ||||||
|  |     config = configparser.ConfigParser() | ||||||
|  |     config.read('config.ini') | ||||||
|  |  | ||||||
|  |     return config | ||||||
							
								
								
									
										21
									
								
								src/my_scrypt.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/my_scrypt.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | import scrypt  # pip install scrypt | ||||||
|  |  | ||||||
|  | def getVerificationHash(password): | ||||||
|  |     salt = "dc73b57736511340f132e4b5521d178afa6311c45e0c25e6a9339038507852a6" | ||||||
|  |  | ||||||
|  |     return getScryptHash(password, salt) | ||||||
|  |  | ||||||
|  | def getEncryptionHash(password): | ||||||
|  |     salt = "2503bfc386bc028772f803887eaaf4d4a5c1019036873e4ba5de79a4efb7e8d8" | ||||||
|  |  | ||||||
|  |     return getScryptHash(password, salt) | ||||||
|  |  | ||||||
|  | def getScryptHash(password, salt): | ||||||
|  |     hashed = scrypt.hash(password=password, | ||||||
|  |                 salt=salt, | ||||||
|  |                 N=16384, | ||||||
|  |                 r=8, | ||||||
|  |                 p=1, | ||||||
|  |                 buflen=32) | ||||||
|  |  | ||||||
|  |     return hashed | ||||||
| @@ -1,8 +1,8 @@ | |||||||
| from flask import Blueprint, jsonify, request | from flask import Blueprint, jsonify, request | ||||||
| from flask_login import login_required | from flask_login import login_required | ||||||
| import hashlib | import hashlib | ||||||
| import configparser |  | ||||||
| import binascii | import binascii | ||||||
|  | import config_provider | ||||||
|  |  | ||||||
| password_api = Blueprint('password_api', __name__) | password_api = Blueprint('password_api', __name__) | ||||||
|  |  | ||||||
| @@ -11,16 +11,12 @@ password_api = Blueprint('password_api', __name__) | |||||||
| def verifyPassword(): | def verifyPassword(): | ||||||
|     req = request.get_json(force=True) |     req = request.get_json(force=True) | ||||||
|  |  | ||||||
|     config = configparser.ConfigParser() |     config = config_provider.getConfig() | ||||||
|     config.read('config.ini') |  | ||||||
|  |  | ||||||
|     hashedPassword = config['Login']['password-hash'].encode('utf-8') |     hashedPassword = config['Login']['passwordHash'].encode('utf-8') | ||||||
|     hashedPasswordBytes = binascii.unhexlify(hashedPassword) |     hashedPasswordBytes = binascii.unhexlify(hashedPassword) | ||||||
|     hashedPasswordSha = hashlib.sha256(hashedPasswordBytes).hexdigest() |     hashedPasswordSha = hashlib.sha256(hashedPasswordBytes).hexdigest() | ||||||
|  |  | ||||||
|     print(req['password']) |  | ||||||
|     print(hashedPasswordSha) |  | ||||||
|  |  | ||||||
|     isValid = req['password'] == hashedPasswordSha |     isValid = req['password'] == hashedPasswordSha | ||||||
|  |  | ||||||
|     return jsonify({ |     return jsonify({ | ||||||
|   | |||||||
| @@ -1,6 +1,8 @@ | |||||||
| import base64 | import base64 | ||||||
| import sqlite3 | import sqlite3 | ||||||
|  |  | ||||||
|  | conn = None | ||||||
|  |  | ||||||
| def dict_factory(cursor, row): | def dict_factory(cursor, row): | ||||||
|     d = {} |     d = {} | ||||||
|     for idx, col in enumerate(cursor.description): |     for idx, col in enumerate(cursor.description): | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user