diff --git a/generate-password.py b/generate-password.py index 4a1cfc921..0b611d7e2 100644 --- a/generate-password.py +++ b/generate-password.py @@ -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!') \ No newline at end of file diff --git a/src/app.py b/src/app.py index 39e10350e..ac8a4f186 100644 --- a/src/app.py +++ b/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) diff --git a/src/password_api.py b/src/password_api.py new file mode 100644 index 000000000..f3f464d17 --- /dev/null +++ b/src/password_api.py @@ -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 + }) \ No newline at end of file diff --git a/static/js/note.js b/static/js/note.js index 55abc5db7..c453f3683 100644 --- a/static/js/note.js +++ b/static/js/note.js @@ -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