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()
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>
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()
If you would like any further information regarding these topics, please refer to this section.