Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

zxcvbn-ios scores password differently than zxcvbn #21

Open
dylanhand opened this issue Jun 15, 2016 · 13 comments
Open

zxcvbn-ios scores password differently than zxcvbn #21

dylanhand opened this issue Jun 15, 2016 · 13 comments

Comments

@dylanhand
Copy link

Hi Leah. Thanks for porting this to iOS. I came across a potential issue:

The password 2-UbvR, for example, is scored differently on zxvcbn-ios vs. Dropbox's online zxcvbn test.

Dropbox's online test:
screen_shot_2016-06-15_at_12_45_33_pm

zxcvbn-ios:
screen shot 2016-06-15 at 12 53 38 pm

Any idea why the iOS version would score a password differently?

@dylanhand dylanhand changed the title zxcvbn-ios gives different result than zxcvbn zxcvbn-ios scores password differently than zxcvbn Jun 15, 2016
@mlehel
Copy link

mlehel commented Jun 21, 2016

Exactly what I have experienced as well, the iOS library scores passwords differently than the JS version, it always gives them a lower scores as far as I could see. Please advise.

@mlehel
Copy link

mlehel commented Jun 24, 2016

Anybody? Any input would be greatly appreciated.

@billymeltdown
Copy link

billymeltdown commented Jun 24, 2016

@mlehel Couldn't tell you myself, but you could step through the routine in a debugger in one lib, then do the same in the debugger for another of the libs to find out what choices are being made differently. For example in iOS you could set a breakpoint where your code calls score and step in. For debugging Javascript you might be able to use your browser, and there's tools like Firebug. For stepping through the Python library you could use the pdb module.

I know that's not answers, but I watch the project and saw your posts so I thought I'd reply. That's where I'd start, I hope it helps!

@mlehel
Copy link

mlehel commented Jun 24, 2016

@billymeltfown: thank you very much for you input, I'll take a look at it, in the meantime I'm also looking forward to some input on behalf of the creators of this module

@mlehel
Copy link

mlehel commented Aug 31, 2016

@dylanhand did you get anywhere with this issue?

@dylanhand
Copy link
Author

@mlehel no. Still hoping we'll hear something from @dropbox or @leah :)

@patreu22
Copy link

patreu22 commented Apr 7, 2017

I'm facing the same problem.
The original version rates the password "hell\o/12" with a score of 2 and "hell\o/123" with a score of 3.

The iOS port accepts "hell\o/12" as a score 3 password and says "hell\o/123" is weaker (only a score of 2).

Does anybody still contribute on this project?

@dylanhand
Copy link
Author

@patreu22 @mlehel I ended up using the JavaScript version inside a JSContext. This way you get consistent results while still running locally.

import JavaScriptCore // make sure to add the framework to your project

fileprivate let jsContext: JSContext! = JSContext()    

// in init:
// load zxvcbn for determining password strength
let zxcvbnPath = Bundle.main.path(forResource: "zxcvbn", ofType: "js")
do {
    let zxcvbnJS = try String(contentsOfFile: zxcvbnPath!, encoding: String.Encoding.utf8)
    jsContext.evaluateScript(zxcvbnJS)
} catch {
    print("error reading zxcvbn.js")
}

// run our local JS zxcvbn function to determine password strength
let password = "hell\o/123"
let result = jsContext.evaluateScript("zxcvbn('\(password)')")
let score = result?.objectForKeyedSubscript("score").toInt32()

@lowe
Copy link

lowe commented Apr 8, 2017

Hi @mlehel,

There's two big reasons that zxcvbn and zxcvbn-ios sometimes give different results:

  • zxcvbn currently has newer data. As examples, it now includes passwords from the Xato '15 password corpus as well as top English wikipedia tokens.

  • over the years, the zxcvbn algorithm has changed and port authors don't always update for a variety of reasons. If you're curious about the changes, the paper has some context in Chapter 4.

If you want the latest updates, I'd recommend using @dylanhand's approach or similar.

@patreu22
Copy link

Hey @dylanhand ,
thanks a lot for your help, using the JavaScript version was our plan to fix that problem, so thank you :)

@likekunkun
Copy link

@dylanhand Thanks 。
I have used your method,However,my score allways -> 0.
Do you know what the reason is?

@likekunkun
Copy link

@patreu22
I have used those method, however score always ->0,
Can you help me. thanks

@AKoulabukhov
Copy link

AKoulabukhov commented Mar 29, 2019

@likekunkun there is one problem with @dylanhand approach. Using String Interpolation is not safe, because password itself can contain ' or ) symbols which would break JS statement.

So instead you should set your password directly into JSContext as variable and then use this variable in evaluateScript. Here is sample code:

    func getPasswordScore(_ password: String) throws -> Int32 {
        guard let jsContext = JSContext() else { throw NSError() }
        
        // Load zxcvbn into JSContext
        guard let zxcvbnPath = Bundle.main.path(forResource: "zxcvbn", ofType: "js") else { throw NSError() }
        let zxcvbnJS = try String(contentsOfFile: zxcvbnPath, encoding: String.Encoding.utf8)
        jsContext.evaluateScript(zxcvbnJS)
        
        // Set password to context, evaluate script and get result
        jsContext.setObject(password, forKeyedSubscript: "password" as NSString)
        guard
            let result = jsContext.evaluateScript("zxcvbn(password)"),
            let value = result.objectForKeyedSubscript("score")
            else { throw NSError() }
        
        return value.toInt32()
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants