Code Snippets

These are code snippets to help you make your code more secure.

Storage

pip install argon2-cffi
from argon2 import PasswordHasher
from argon2.exceptions import VerifyMismatchError

def hash_password(password):
    ph = PasswordHasher()
    pw_hash = ph.hash(password)
    return pw_hash


def verify(pw_hash, password):
    ph = PasswordHasher()
    try:
        return ph.verify(pw_hash, password)
    except VerifyMismatchError:
        return False


def main():
    pw_hash = hash_password('s3cr3t')
    print(pw_hash)
    print(verify(pw_hash, 's3cr3t'))
    print(verify(pw_hash, 's3cr4t'))
    return None


if __name__ == '__main__':
    main()
pip install bcrypt
import bcrypt

def hash_password(password):
    # bcrypt.gensalt() takes an argument (in the form of eg (rounds=16))
    # which increases security, but also the cost factor
    pw_hash = bcrypt.hashpw(password.encode(), bcrypt.gensalt())
    return pw_hash


def verify(pw_hash, password):
    return bcrypt.checkpw(password.encode(), pw_hash)


def main():
    pw_hash = hash_password('s3cr3t')
    print(pw_hash)
    print(verify(pw_hash, 's3cr3t'))
    print(verify(pw_hash, 's3cr4t'))
    return None


if __name__ == '__main__':
    main()

Policy

To customize this code to your needed specifications, click this button!

Customize

    Password policy compliant with:

    Password length:

    Strength Checker

    Using the Strength Checker allows you to restrict the use of common weak passwords, and warn the user of patterns that would weaken a chosen password.


    Composition requirements

    This allows you to restrict the use of passwords that do not meet certain requirements in their composition (eg passwords must contain special characters). While it is a common practice, neither OWASP nor NIST currently recommend enforcing it.

function composition() {
    var password = document.getElementById('password');
    //at least one number
    var number = /(?=.*\d)/;
    //at least one lowercase and one uppercase letter
    var upper_lower = /(?=.*[a-z])(?=.*[A-Z])/;
    // at least one special character
    var special = /[^A-Za-z0-9]/;
    return number.test(password.value) && upper_lower.test(password.value) && special.test(password.value);
}

function length() {
    var password = document.getElementById('password');
    // at least eight, at most 64 characters
    var length = /^.{8,64}$/;
    return length.test(password.value);
}

var login = document.getElementById('login-button');
var validated = document.getElementById('login-validation');

login.addEventListener('click', function() {

    console.log(composition());
    console.log(length());

    var validate = composition() && length();

    if(validate !== true) {
        validated.innerHTML = "Password is not valid!" + "<br>" + "Must be between 8 and 64 characters, contain at least one upper- and one lowercase letter, a number and a special character."; 
    }
    else {
        validated.innerHTML = "Password is valid!";
    }
});

var meter = document.getElementById('password-strength-meter');
var text = document.getElementById('password-strength-text');
                                                
var strength = {
    0: "Worst",
    1: "Bad",
    2: "Weak",
    3: "Good",
    4: "Strong"
}

password.addEventListener('input', function()
{
var val = password.value;
var result = zxcvbn(val);

// Update the password strength meter
meter.value = result.score;

// Update the text indicator
if(val !== "") {
    text.innerHTML = "Strength: " + "<strong>" + strength[result.score] + "</strong>" + "<br>" + "<span class='feedback'>" + result.feedback.warning + "<br>" + result.feedback.suggestions + "</span>"; 
}
else {
    text.innerHTML = "";
}
});

<!DOCTYPE html>
<html>
<body>

    <div class="container">
        <div class="row">
            <div class="col m6">
                <h2 class="center-align">Login</h2>
                <div class="row">
                    <form class="col s12">
                        <div class="row">
                            <div class="input-field col s12">
                                <input id="email" type="email" class="validate">
                                <label for="email">Email</label>
                            </div>
                        </div>
                        <div class="row">
                            <div class="input-field col s12">
                                <input id="password" type="password" class="validate">
                                <label for="password">Password</label>
                                <meter max="4" id="password-strength-meter"></meter>
                                <p id="password-strength-text"></p>
                            </div>
                        </div>
                        <div class="divider"></div>
                        <div class="row">
                            <div class="col m12">
                                <p class="right-align">
                                    <button id="login-button" class="btn btn-large waves-effect waves-light" type="button" name="action">Login</button>
                                    <p id="login-validation"></p>
                                </p>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/zxcvbn/4.2.0/zxcvbn.js"></script>
    <script type="text/javascript" src="js/scripts.js"></script>
</body>
</html>

Two Factor Authentication

pip install pyotp
#!/usr/bin/env python3

import pyotp


def generate_second_factor(shared_secret):

    return pyotp.TOTP(shared_secret)


def generate_uri(second_factor, user_mail):

    return second_factor.provisioning_uri(user_mail, issuer_name="Your Secure App")


def main():

    shared_secret = pyotp.random_base32()
    # The shared secret has to be stored alongside the other infos on the user to verify them in the future.
    second_factor = generate_second_factor(shared_secret)
    print(second_factor.verify(second_factor.now()))

    user_mail = "alice@google.com"
    provisioning_uri = generate_uri(second_factor, user_mail)
    # The provisioning uri can be used to generate a QR-code, 
    # which the user can scan using apps like the Google Authenticator
    print(provisioning_uri)
    
    # It might be advisable to have the user verify their account once immediately after 
    # setting up the second factor, to avoid locking them out at a later date


if __name__ == '__main__':
    main()

Further Information

If you would like any further information regarding these topics, please refer to this section.