mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 19:49:01 +01:00 
			
		
		
		
	verifying password with hash on the backend to make sure we don't decrypt garbage and also to make sure that everything is encrypted with same password/key
This commit is contained in:
		
							parent
							
								
									53d327e435
								
							
						
					
					
						commit
						87c1a95ccc
					
				| @ -2,7 +2,8 @@ | ||||
| 
 | ||||
| import getpass | ||||
| 
 | ||||
| import bcrypt  # pip install bcrypt | ||||
| import scrypt  # pip install scrypt | ||||
| import binascii | ||||
| 
 | ||||
| password1 = getpass.getpass() | ||||
| 
 | ||||
| @ -11,9 +12,17 @@ print('Repeat the same password:') | ||||
| password2 = getpass.getpass() | ||||
| 
 | ||||
| if password1 == password2: | ||||
|     salt = bcrypt.gensalt() | ||||
|     # salt is constant | ||||
|     salt = "dc73b57736511340f132e4b5521d178afa6311c45e0c25e6a9339038507852a6" | ||||
| 
 | ||||
|     print('Generated hash:') | ||||
|     print(bcrypt.hashpw(password1, salt)) | ||||
|     hashed = scrypt.hash(password=password1, | ||||
|                            salt=salt, | ||||
|                            N=16384, | ||||
|                            r=16, | ||||
|                            p=1, | ||||
|                            buflen=32) | ||||
| 
 | ||||
|     print('Generated password hash:') | ||||
|     print(binascii.hexlify(hashed)) | ||||
| else: | ||||
|     print('Entered passwords are not identical!') | ||||
							
								
								
									
										22
									
								
								src/app.py
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								src/app.py
									
									
									
									
									
								
							| @ -1,6 +1,7 @@ | ||||
| import os | ||||
| 
 | ||||
| import bcrypt | ||||
| import binascii | ||||
| import scrypt | ||||
| import configparser | ||||
| from flask import Flask, request, send_from_directory | ||||
| from flask import render_template, redirect | ||||
| @ -11,6 +12,7 @@ from notes_api import notes_api | ||||
| from sql import connect | ||||
| from tree_api import tree_api | ||||
| from notes_move_api import notes_move_api | ||||
| from password_api import password_api | ||||
| 
 | ||||
| config = configparser.ConfigParser() | ||||
| config.read('config.ini') | ||||
| @ -20,6 +22,7 @@ app.secret_key = config['Security']['flaskSecretKey'] | ||||
| app.register_blueprint(tree_api) | ||||
| app.register_blueprint(notes_api) | ||||
| app.register_blueprint(notes_move_api) | ||||
| app.register_blueprint(password_api) | ||||
| 
 | ||||
| class User(UserMixin): | ||||
|     pass | ||||
| @ -53,11 +56,26 @@ connect(documentPath) | ||||
| 
 | ||||
| hashedPassword = config['Login']['password-hash'].encode('utf-8') | ||||
| 
 | ||||
| 
 | ||||
| def verify_password(hex_hashed_password, guessed_password): | ||||
|     hashed_password = binascii.unhexlify(hex_hashed_password) | ||||
| 
 | ||||
|     salt = "dc73b57736511340f132e4b5521d178afa6311c45e0c25e6a9339038507852a6" | ||||
| 
 | ||||
|     hashed = scrypt.hash(password=guessed_password, | ||||
|                          salt=salt, | ||||
|                          N=16384, | ||||
|                          r=16, | ||||
|                          p=1, | ||||
|                          buflen=32) | ||||
| 
 | ||||
|     return hashed == hashed_password | ||||
| 
 | ||||
| @app.route('/login', methods=['POST']) | ||||
| def login_post(): | ||||
|     inputPassword = request.form['password'].encode('utf-8') | ||||
| 
 | ||||
|     if request.form['username'] == user.id and bcrypt.hashpw(inputPassword, hashedPassword) == hashedPassword: | ||||
|     if request.form['username'] == user.id and verify_password(hashedPassword, inputPassword): | ||||
|         rememberMe = True if 'remember-me' in request.form else False | ||||
| 
 | ||||
|         login_user(user, remember=rememberMe) | ||||
|  | ||||
							
								
								
									
										28
									
								
								src/password_api.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/password_api.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | ||||
| from flask import Blueprint, jsonify, request | ||||
| from flask_login import login_required | ||||
| import hashlib | ||||
| import configparser | ||||
| import binascii | ||||
| 
 | ||||
| password_api = Blueprint('password_api', __name__) | ||||
| 
 | ||||
| @password_api.route('/password/verify', methods = ['POST']) | ||||
| @login_required | ||||
| def verifyPassword(): | ||||
|     req = request.get_json(force=True) | ||||
| 
 | ||||
|     config = configparser.ConfigParser() | ||||
|     config.read('config.ini') | ||||
| 
 | ||||
|     hashedPassword = config['Login']['password-hash'].encode('utf-8') | ||||
|     hashedPasswordBytes = binascii.unhexlify(hashedPassword) | ||||
|     hashedPasswordSha = hashlib.sha256(hashedPasswordBytes).hexdigest() | ||||
| 
 | ||||
|     print(req['password']) | ||||
|     print(hashedPasswordSha) | ||||
| 
 | ||||
|     isValid = req['password'] == hashedPasswordSha | ||||
| 
 | ||||
|     return jsonify({ | ||||
|         'valid': isValid | ||||
|     }) | ||||
| @ -204,9 +204,7 @@ function addRecentNote(noteTreeId, noteContentId) { | ||||
| function deriveEncryptionKey(password) { | ||||
|     // why this is done is explained here: https://github.com/ricmoo/scrypt-js - "Encoding notes"
 | ||||
|     const normalizedPassword = password.normalize('NFKC'); | ||||
|     // use password as a base for salt (which is itself salted with constant) so that we don't need to store it
 | ||||
|     // this means everything is encrypted with the same salt.
 | ||||
|     const salt = sha256("Jg&)hZ$" + normalizedPassword + "*P7j."); | ||||
|     const salt = "dc73b57736511340f132e4b5521d178afa6311c45e0c25e6a9339038507852a6"; | ||||
| 
 | ||||
|     const passwordBuffer = new buffer.SlowBuffer(normalizedPassword); | ||||
|     const saltBuffer = new buffer.SlowBuffer(salt); | ||||
| @ -228,7 +226,24 @@ function deriveEncryptionKey(password) { | ||||
|             else if (key) { | ||||
|                 console.log("Computation took " + (new Date().getTime() - startedDate.getTime()) + "ms"); | ||||
| 
 | ||||
|                 resolve(key); | ||||
|                 $.ajax({ | ||||
|                     url: baseUrl + 'password/verify', | ||||
|                     type: 'POST', | ||||
|                     data: JSON.stringify({ | ||||
|                         password: sha256(key) | ||||
|                     }), | ||||
|                     contentType: "application/json", | ||||
|                     success: function (result) { | ||||
|                         if (result.valid) { | ||||
|                             resolve(key); | ||||
|                         } | ||||
|                         else { | ||||
|                             alert("Wrong password"); | ||||
| 
 | ||||
|                             reject(); | ||||
|                         } | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|             else { | ||||
|                 // update UI with progress complete
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 azivner
						azivner