Use zxcvbn for password strength estimation

pull/2/head
moneromooo.monero 8 years ago
parent b882de8e1c
commit fbe19d23b7

@ -1,6 +1,7 @@
#include "WalletManager.h"
#include "Wallet.h"
#include "wallet/wallet2_api.h"
#include "zxcvbn-c/zxcvbn.h"
#include <QFile>
#include <QFileInfo>
#include <QDir>
@ -241,6 +242,21 @@ QUrl WalletManager::localPathToUrl(const QString &path) const
return QUrl::fromLocalFile(path);
}
double WalletManager::getPasswordStrength(const QString &password) const
{
static const char *local_dict[] = {
"monero", "fluffypony", NULL
};
if (!ZxcvbnInit("zxcvbn.dict")) {
fprintf(stderr, "Failed to open zxcvbn.dict\n");
return 0.0;
}
double e = ZxcvbnMatch(password.toStdString().c_str(), local_dict, NULL);
ZxcvbnUnInit();
return e;
}
WalletManager::WalletManager(QObject *parent) : QObject(parent)
{
m_pimpl = Monero::WalletManagerFactory::getWalletManager();

@ -114,6 +114,8 @@ public:
Q_INVOKABLE qint64 addi(qint64 x, qint64 y) const { return x + y; }
Q_INVOKABLE qint64 subi(qint64 x, qint64 y) const { return x - y; }
Q_INVOKABLE double getPasswordStrength(const QString &password) const;
signals:
void walletOpened(Wallet * wallet);

@ -26,6 +26,7 @@
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import moneroComponents.WalletManager 1.0
import QtQuick 2.2
import "../components"
import "utils.js" as Utils
@ -76,7 +77,7 @@ Item {
wizard.nextButton.enabled = passwordItem.password === retypePasswordItem.password
// scorePassword returns value from 1..100
var strength = Utils.scorePassword(passwordItem.password)
var strength = walletManager.getPasswordStrength(passwordItem.password);
// privacyLevel component uses 1..13 scale
privacyLevel.fillLevel = Utils.mapScope(1, 100, 1, 13, strength)

@ -1,37 +1,5 @@
.pragma library
// grabbed from SO answer page: http://stackoverflow.com/questions/948172/password-strength-meter
function scorePassword(pass) {
var score = 0;
if (!pass)
return score;
// award every unique letter until 5 repetitions
var letters = {};
for (var i=0; i<pass.length; i++) {
letters[pass[i]] = (letters[pass[i]] || 0) + 1;
score += 5.0 / letters[pass[i]];
}
// bonus points for mixing it up
var variations = {
digits: /\d/.test(pass),
lower: /[a-z]/.test(pass),
upper: /[A-Z]/.test(pass),
nonWords: /\W/.test(pass),
}
var variationCount = 0;
for (var check in variations) {
variationCount += (variations[check] === true) ? 1 : 0;
}
score += (variationCount - 1) * 10;
return parseInt(score);
}
function mapScope (inputScopeFrom, inputScopeTo, outputScopeFrom, outputScopeTo, value) {
var x = (value - inputScopeFrom) / (inputScopeTo - inputScopeFrom);
var result = outputScopeFrom + ((outputScopeTo - outputScopeFrom) * x);